许多带有套接字的消息队列

时间:2019-07-05 04:58:19

标签: c

我有一个程序。它创建一个客户端套接字(非阻塞),并且还将派生许多子进程。子进程仅从消息队列接收消息,然后将其写入套接字。如果同时有许多子进程从其消息队列接收消息并将其写入套接字,会发生什么情况?

下面是代码:

//create socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
connect(sockfd, (struct sockaddr *)&sin, sizeof(sin));

//set the socket to be non-block.
int fs = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, fs | O_NONBLOCK);

//fork many child processes for receiving message from message queue
for (i = 0, lp = listhead; lp != NULL; lp = lp->next) {
    switch (fork()) {
    case -1:
        slogsyscall("fork", errno);
        killpg(0, SIGTERM);
        _exit(EXIT_SYSCALL);
    case 0: /* child process */
        for(;;) {
            //receive message from message queue
            int rcvlen = msgrcv(lp->msqid, &pmsg.mtype, MAX_MTEXT, 0, 0);

            //write the received message to the non-block socket 'sockfd'
            write(sockfd, pmsg.msg, rcvlen);
        }
    default:
        break;
    }
}

我希望发送到非阻塞套接字'sockfd'的所有消息都将正确发送,并且不会互相干扰。

例如:

child process 1:   got message 'cat' from queue, and send it to sockfd
child process 2:   got message 'dog' from queue, and send it to sockfd
child process 3:   got message 'chicken' from queue, and send it to sockfd
child process 4:   got message 'monkey' from queue, and send it to sockfd

套接字会像下面这样将消息放入套接字缓冲区吗: catdogchickenmonkey,无特定顺序。否则它们会像cogdatchikmonkeyen一样互相干扰?

如果它们相互干扰,那么我该如何防止这种情况发生?

如果我将套接字更改为阻塞状态,那会发生什么?

1 个答案:

答案 0 :(得分:0)

如注释中所述,您可以使用F_SETLK。 我正在基于手册页编写以下代码,尚未编译或测试。

struct flock fl = {0};
int result;

/* Lock range for writing */
fl.l_type = FL_WRLCK;  /* Write lock */
/* from current to len bytes */
fl.l_whence = SEEK_CUR;
fl.l_start = 0;
fl.l_len = strlen(pmsg.msg); /* typecasting required */
fl.pid = mypid;

result = fcntl(sockfd, F_SETLK, &fl);
if (rc == -1) {
 perror("fcntl");
 /* Retry or something */
}