atomic write pipe

 

阅读 skynet 代码 socket_server 部分,发现对 socket 的写操作流程是这样的:

1. 各个服务(各线程)将数据写到 sendctrl_fd,这是一个 pipe 的 写端

2. ctrl_cmd 函数从 recvctrl_fd 读出数据,然后写到真正的 socketfd

 

在第一步中,多个线程向 sendctrl_fd 写数据,但是代码中并没有给 sendctrl_fd 加锁。

 1 static void
 2 send_request(struct socket_server *ss, struct request_package *request, char type, int len) {
 3     request->header[6] = (uint8_t)type;
 4     request->header[7] = (uint8_t)len;
 5     for (;;) {
 6         int n = write(ss->sendctrl_fd, &request->header[6], len+2);
 7         if (n<0) {
 8             if (errno != EINTR) {
 9                 fprintf(stderr, "socket-server : send ctrl command error %s.\n", strerror(errno));
10             }
11             continue;
12         }
13         assert(n == len+2);
14         return;
15     }
16 }

经过各种搜索得出结论:

写 pipe 的数据大小如果小于等于 PIPE_BUF(4k),那么这个写操作是 atomic 的。如果超过了这个 PIPE_BUF,那就不能保证咯。。

 

http://stackoverflow.com/questions/4624071/pipe-buffer-size-is-4k-or-64k

https://docs.oracle.com/cd/E19683-01/806-6546/pipe6-7/index.html

http://man7.org/linux/man-pages/man7/pipe.7.html

http://stackoverflow.com/questions/9701757/when-to-use-pipes-vs-when-to-use-shared-memory

http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#pipes

 

posted on 2017-02-11 10:18  明天有风吹  阅读(301)  评论(0编辑  收藏  举报

导航

+V atob('d2h5X251bGw=')

请备注:from博客园