简体   繁体   中英

Many Message Queues with socket

I've a program. it creates a client socket(non-block), and also it will fork many child processes. The child processes just receiving messages from message queue and write it to the socket. What happens if at the same time many child processes received message from their message queue and write it to the socket?

Below is the code:

//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;
    }
}

I expect all the messages which sent to the non-block socket 'sockfd' will correctly sent and will not interfere with each other.

for example:

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

Does the socket will put the message in the socket buffer like this: catdogchickenmonkey with no particular order. or they will interfere with each other like cogdatchikmonkeyen ?

If they interfere with each other, then how can i prevent this from happening?

If I change the socket to be blocking, then what happens?

As discussed in the comments, you can use F_SETLK. I am writing below code on the basis of manpage and have not compiled or tested.

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 */
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM