我所用的软件架构,使用pipe来实现线程之间的大量数据的传输。在实际操作中,pipe中传输的是数据的指针,而不是数据本身。
但是在调试过程中,我发现,如果我尝试往pipe里面write10000个指针,而不取时,线程会阻塞。因此怀疑与pipe size有关。
会不会与ulimit有关?
admin@xxxx:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 13140 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 8192000 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 13140 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
用ulimit -a查看,这其中的pipe size 为8*512字节,限制比我实际遇到的问题还要小,而且无法修改ulimit的pipe size,使他变大。
换一种思路,通过man 7 pipe来查看,原来pipe的空间目前是默认值65536,而我用的64位计算机,一个指针的大小是8字节,也就是说pipe空间最多可以存放8192(65536/8)个指针。经过实验,果然连续往pipe中写入第8193个指针时,会被阻塞住。要想扩充的话,可以用fcntl来进行。下面是摘抄的英语原文。
In Linux versions before 2.6.11, the capacity of a pipe was the same as the system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11, the pipe capacity is 65536 bytes. Since Linux 2.6.35, the default pipe capacityis 65536 bytes, but the capacity can be queried and set using the fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ operations. See fcntl(2) for more information.
在pipe创建之后,添加如下代码:
fcntl(p_pipeline->pipes[1], F_SETPIPE_SZ, 131072);
加上如下头文件之后:
#include <sys/types.h> #include <unistd.h> #include <fcntl.h>
进行编译,但是报错,
error: 'F_SETPIPE_SZ' undeclared (first use in this function)
在源文件的所有h文件之前,加入下面的宏定义。
#define _GNU_SOURCE
这下就能编译通过了。
再做实验验证,连续往pipe中写入10000个指针,也没有问题了。