我正在研究IPC,并且有一个关于System V消息队列使用的基本示例.代码非常简单:主进程创建消息队列,然后使用fork()并开始无限循环地发送消息,但会有一些延迟.子进程在一个循环中接收消息,其逻辑是:Hibernate -接收所有累积-Hibernate .
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h>
typedef struct
{
int value;
} messageText;
typedef struct
{
long mtype;
messageText mtext;
} queueMessage;
int main()
{
key_t queueKey = ftok(__FILE__, 'M');
int msgQueue = msgget(queueKey, IPC_CREAT | 0660);
pid_t pid = fork();
if (0 == pid)
{
// never returns
child_main(msgQueue);
abort();
}
queueMessage msg =
{
.mtype = 1,
.mtext = { 0 }
};
for (int i = 0; /* void */ ; ++i)
{
msg.mtext.value = i;
int rc = msgsnd(msgQueue, &msg, sizeof(msg.mtext), 0);
if (rc == -1)
perror("msgsnd");
usleep(250000); // 0.25 sec
struct msqid_ds queueInfo;
msgctl(msgQueue, IPC_STAT, &queueInfo);
printf("Messages in queue = %ld\n", queueInfo.msg_qnum);
}
return 0;
}
void child_main(int msgQueue)
{
queueMessage msg = { 0 };
int msgTyp = 0; // 1st message in queue
int msgRcvFlg = IPC_NOWAIT | MSG_NOERROR;
while (1)
{
while (1)
{
int rc = msgrcv(msgQueue, &msg, sizeof(msg.mtext), msgTyp, msgRcvFlg);
if (-1 == rc)
{
if (errno == ENOMSG)
{
goto sleep;
}
else
{
perror("msgrcv");
exit(EXIT_FAILURE);
}
}
printf("read: %d\n", msg.mtext.value);
}
sleep:
usleep(5000000); // 5 sec.
}
}
因此,预期的行为是父消息在队列中累积,直到子消息被唤醒、读取并再次Hibernate ().为了判断它的逻辑是否正确,每次家长发送新消息时,我都会打印消息编号.但实际行为是,由于某种原因,队列内容似乎被重置,因此子元素收到的消息很少.父母睡的时间越长越少 当子元素try 接收消息时,消息仍在队列中.
这是父母睡眠时间的输出示例 0.25秒.
Messages in queue = 1
Messages in queue = 2
Messages in queue = 3
Messages in queue = 4
Messages in queue = 5
Messages in queue = 0
Messages in queue = 1
Messages in queue = 2
Messages in queue = 3
read: 8
read: 9
read: 10
read: 11
Messages in queue = 0
Messages in queue = 1
Messages in queue = 0
...
ipcs -l
个yields
------ Messages Limits --------
max queues system wide = 32000
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 18014398509465599
max total shared memory (kbytes) = 18446744073709551612
min seg size (bytes) = 1
------ Semaphore Limits --------
max number of arrays = 32000
max semaphores per array = 32000
max semaphores system wide = 1024000000
max ops per semop call = 500
semaphore max value = 32767
我在手册页中没有找到任何关于这种行为的信息.有人能解释一下吗?