C中父进程和子进程中TAILQ队列的同步问题

rks48beu  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(58)

有5个子进程和1个父进程(为了简化,我们只取1个子进程)。一些计算发生在子进程中,之后它们必须将信息传递给父进程。我使用TAILQ队列进行消息传递。问题是运行下面的程序会导致完全空的输出。尽管队列在分叉之前被初始化,我们得到的是同一个队列的两个示例,它们彼此没有联系。如果你从一个子进程调用TAILQ_FIRST,一切都正常。我如何同步队列?

#define _SVID_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/queue.h>

struct message
{
    int num;
    char status;
    TAILQ_ENTRY(message) queue_entry;
};

struct message_queue
{
    TAILQ_HEAD(head_t, message) head;
} queue;

int main()
{
    TAILQ_INIT(&queue.head);

    pid_t pid;
    pid = fork();

    if (!pid) // child process
    {
        while(1)
        {
            struct message* p = malloc(sizeof(struct message));
            p->num = 1;
            p->status = 's';
            TAILQ_INSERT_TAIL(&queue.head, p, queue_entry);
        }
    }
    else // parent process
    {
        while (1)
        {
            struct message* p = TAILQ_FIRST(&queue.head);

            if (p)
            {
                TAILQ_REMOVE(&queue.head, p, queue_entry);
            }

            if (p)
            {
                printf("Num %d and status %c", p->num, p->status);
                free(p);
            }
        }

    }

    return 0;
}

字符串

mrwjdhj3

mrwjdhj31#

扩展我的评论; TAILQ机制只在单个进程中工作,而不是跨父/子进程。
我们得到的是同一个队列的两个示例,它们彼此之间没有联系。
是的,你理解的没错。
当你调用fork()时,它实际上创建了第二个与第一个进程相同的进程,并复制了所有程序和内存区域,唯一的区别是pid变量的返回值:它在子进程中为零,在父进程中为非零(<0也是一个错误)。
这意味着在fork上,现在有队列的两个私有副本,每个进程都在其上“正确”操作,但没有操作另一端的合作进程。
我记得很清楚,我试图让我的头周围的概念,一个单一的功能行为是这样的:-)
在你的例子中,子进程能够一遍又一遍地添加消息,但是没有消费者。父进程在等待一些事情发生,但是它永远不会发生。
如果你的任务仅限于父进程和子进程之间的通信,管道是一个很好的机制,但是如果你需要更通用的进程间通信,那么POSIX消息队列是一个不错的选择,但是可能还有其他的。

相关问题