1

我需要在一个程序中创建很多FIFO队列,用于同一进程中线程之间的通信。

我想我可以使用 pipe() 来达到这个目的,因为通过这种方式,我可以在从队列中获取节点的线程上使用 select 或 poll。

        int* fd_pipe = (int*)malloc(2*sizeof(int));
        pipe(fd_pipe);

现在的问题是如何将指针放入队列,因为每个节点都是一个结构,我想将指针放入队列中,例如

typedef{ 结构数据包 *pkt; 结构信息*信息;整数序列;}节点;

  on threads which put node into the queue:

   Node* node = (Node*)malloc(sizeof(Node));
   Node->info = ...;
   Node->seq = ...;
   Node->pkt = ...;
   write(fd_pipe[1], node, sizeof(node));

  on threads which read node from the queue:

   char buf[1000];
   read(fd_pipe[0], buf, sizeof(node))
   Node* mynode = (Node*)buf;

那么 mynode 就是我想要的。

我的程序有什么问题吗?特别是严格的别名或双关语问题?谢谢!

4

1 回答 1

2

您没有别名问题。这里我看到的唯一问题是read(fd_pipe[0], buf, sizeof(node)),这应该是read(fd_pipe[0], buf, sizeof(Node *))

我不知道你为什么在这里使用 char 缓冲区,我更喜欢

Node *node;
if (read(fd_pipe[0], &node, sizeof(node)) <= 0) {
    // error, deal with it
}

它更简单,更清晰。

现在,您的代码只有在使用默认的阻塞 i/o 时才能正常工作。此外,从技术上讲,您应该处理短读/写,但如果读/写大小小于 PIPE_BUF(总是比指针大得多),则管道上的写/读是原子的

在写入之前,您的代码中有一些关于内存同步的灰色区域,但由于这是一个系统调用,它会起作用。

管道是线程之间通信的一种不寻常的方式。通常,人们使用内存队列在线程之间进行通信。一个例子是http://www.boost.org/doc/libs/1_53_0/doc/html/boost/lockfree/queue.html

于 2013-05-19T17:00:48.190 回答