Многие очереди сообщений с сокетом - PullRequest
0 голосов
/ 05 июля 2019

У меня есть программа.он создает клиентский сокет (неблокированный), а также разветвляет многие дочерние процессы.Дочерний процесс обрабатывает только получение сообщений из очереди сообщений и запись их в сокет.Что произойдет, если одновременно многие дочерние процессы получат сообщение из своей очереди сообщений и запишут его в сокет?

Ниже приведен код:

//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 голосов
/ 05 июля 2019

Как обсуждалось в комментариях, вы можете использовать F_SETLK.Я пишу ниже код на основе manpage и не скомпилирован или проверен.

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 */
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...