百科狗-知识改变命运!
--

msg_get_queue() - semaphore函数

乐乐1年前 (2023-11-21)阅读数 17#技术干货
文章标签返回值

msg_get_queue()

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

Create or attach to a message queue

说明

msg_get_queue(int $key[,int $perms= 0666]): resource

msg_get_queue() returns an id that can be used to access the System V message queue with the given$key. The first call creates the message queue with the optional$perms. A second call to msg_get_queue() for the same$keywill return a different message queue identifier, but both identifiers access the same underlying message queue.

参数

$key

msg_get_queue() - semaphore函数

Message queue numeric ID

$perms

Queue permissions. Default to 0666. If the message queue already exists, the$permswill be ignored.

返回值

Returns a resource handle that can be used to access the System V message queue.

参见

  • msg_remove_queue()Destroy a message queue
  • msg_receive()Receive a message from a message queue
  • msg_send()Send a message to a message queue
  • msg_stat_queue()Returns information from the message queue data structure
  • msg_set_queue()Set information in the message queue data structure
A simple Sample to introduce Message Queue. 
If you are getting this message on your *NIX box:
Warning: msg_get_queue() [function.msg-get-queue]: failed for key 0x12345678: No space left on device in /path/to/script.php on line 1
you may use the command "ipcrm" as root to clear the message queue. Use "man ipcrm" to get more info on it.
The default setting for maximum messages in the queue is stored in /proc/sys/fs/mqueue/msg_max. To increase it to a maximum of 100 messages, just run:
echo 100 > /proc/sys/fs/mqueue/msg_max
Please ensure to follow a good programming style and close/free all your message queues before your script exits to avoid those warning messages.
If you are getting the following message (on Linux):
Warning: msg_get_queue() [function.msg-get-queue]: failed for key 0x12345678: No space left on device in /path/to/script.php on line 1
aside from what [others have] suggested, you should also check and set an appropriate value for kernel parameter kernel.msgmni, e.g. sysctl -w kernel.msgmni=256
I find it hard to work out how to really use this reliably particularly in respect to collisions.
It maps to SysV IPC msgget.
As I see it you have three options...
1. Manage the IDs yourself, allocating various ranges or using some kind of centralised mechanism.
2. Use ftok. This attempts to find a unique ID, though it's not guaranteed to be unique or constant in absolutely every circumstance. It relies on using a file, from which it uses bits from the inode and dev it expects to be unique. It's the standard way and as long as there's nothing too unusual it should probably work (but might not survive radical FS changes).
3. Use 0 as the key, which appears to map to IPC_PRIVATE, a magic value which if provided as a key creates a new queue each time (without a key in effect).
Unfortunately option #3 is of limited use in PHP.
In C that is useful might be useful as the queue resource is just identified by an int and can be passed around.
In PHP its utility is questionable as only the resource can be passed within a single process. It's not possible to pass the resource with serialize / unserialize even though it's just a wrapped int.
The msqid returned isn't exactly unpredictable either so can quite easily be accidentally accessed. The first one I got was 0.
If you create a queue like this you'll find it very annoying as it wont be possible to delete it via PHP.
Like all IO it's worth wrapping this function and launching an exception if the input is 0.
Lack of IPC_EXCL makes me unhappy. Of course, you can use ftok() to generate a unique key. This code is not allmighty, another process under the same user can open the queue and function returns true. But in some situation it could help.
code: 
// Here is an example of working with message queues.
// if you have forked processes, this could be a great way of passing
// out work to them
// create the message queue
// pick a file..
 $key_t = msg_get_queue(ftok("/tmp/php_msgqueue.stat", 'R'),0666 | IPC_CREAT);
  // place two messages on the queue
  if (!msg_send ($key_t, 1, 'This is message #1', true, true, $msg_err))
    echo "Msg not sent because $msg_err\n";
  if (!msg_send ($key_t, 1, 'This is message #2 ', true, true, $msg_err))
    echo "Msg not sent because $msg_err\n";
   
  // lets look at the queue structure 'msg_qnum' is really what we want to see
  // it should be '2'
  print_r(msg_stat_queue($key_t));
  
  // pull off the stack
    if (msg_receive ($key_t, 1, $msg_type, 16384, $msg, true, 0, $msg_error)) {
      if ($msg == 'Quit');
      echo "$msg\n"; // prints 'This is message #1'
    } else {
      echo "Received $msg_error fetching message\n";
    }
  // look at the structure again, ms_qnum should be '1'  
  print_r(msg_stat_queue($key_t));
    if (msg_receive ($key_t, 1, $msg_type, 16384, $msg, true, 0, $msg_error)) {
      if ($msg == 'Quit');
      echo "$msg\n"; // prints 'This is message #2'
    } else {
      echo "Received $msg_error fetching message\n";
    }
  // look at the structure again, ms_qnum should be '0', no more messages on the queue
  print_r(msg_stat_queue($key_t)); 
  // get rid of the queue we created
  msg_remove_queue ($key_t);
IPC_CREAT has no effect in this function. The PHP source code (file sysvmsg.c) reveals that only if msgget(key,0) fails, msgget(key, IPC_CREAT | IPC_EXCL | perms) is used.

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)