创建write()阻塞的场景

时间:2015-03-25 17:11:09

标签: c linux blocking

我有这个简单的C程序:

#include <stdio.h>

int main (int argc, char *argv[])
{
  printf ("Hello, world\n");

  return 0;
}

如果我对已编译的程序进行straf,则printf()变为write():

$ strace ./hw > x
execve("./hw", ["./hw"], [/* 19 vars */]) = 0
...
write(1, "Hello, world\n", 13)          = 13
...

我的问题如下:我希望操作系统在执行write()调用后阻止程序执行。作为一个简单的非root用户,是否有可能创建这样的场景?请注意,我无法更改程序代码。

我的直觉告诉我它应该,但我无法找到解决方案。想象一下write()会写入一个文件描述符,该文件描述符是一个无缓冲的字符设备。这样的设备,不会强制write()阻塞吗?

2 个答案:

答案 0 :(得分:6)

write系统调用将数据复制到与文件描述符关联的内核缓冲区中。只要可以缓冲,呼叫就不会阻塞。但是,如果您将足够的数据写入慢速输出设备,则最终write将阻止。

要阻止写入几个字节需要做一些工作。这是一种方法:

首先,创建一个命名管道:

mkfifo /tmp/the_fifo

任何打开 /tmp/the_fifo进行写入的尝试都会阻止,直到某个进程打开fifo进行读取。您可以打开fifo进行阅读,而无需阅读以下内容:

sleep 1000 < /tmp/the_fifo &

现在你可以填充fifo缓冲区:

yes > /tmp/the_fifo &

此时,您的程序在尝试写入/tmp/fifo时应该阻止。

当你完成后,不要忘记终止后台进程并删除命名管道。

答案 1 :(得分:1)

如果您写入管道并且没有人读取该管道,它最终会填满。我可能错了,默认的Linux管道大小是64KB。

尝试将应用程序的输出连接到一个永远不会读取其标准输入的应用程序,如下所示:

./hw | sleep 1000

sleep从不读取其标准输入,这样您就可以轻松填充管道。