1

假设我的程序有一些线程,因为文件描述符在线程之间共享,如果我调用close(stderr),所有线程都不会输出到stderr. 我的问题:有没有办法关闭stderr一个线程的输出,而不是其他线程?

更具体地说,我的程序的一个线程调用了第三方库函数,它保持输出警告消息,我知道这些消息是无用的。但我无权访问这个第三方库资源。

4

3 回答 3

3

不是。文件描述符是一个进程中所有线程都可以使用的全局资源。当然,标准错误是文件描述符编号 2,因此它是一个全局资源,您无法阻止第三方代码对其进行写入。

如果问题严重到需要治疗,您可以:

int fd2_copy = dup(2);
int fd2_null = open("/dev/null", O_WRONLY);

在调用第三方库函数之前:

dup2(fd2_null, 2);
third_party_library_function();
dup2(fd2_copy, 2);

基本上,在第三方库使用期间,将标准错误切换为/dev/null,功能后恢复正常输出。

当然,您应该对系统调用进行错误检查。

这样做的缺点是,当这个线程正在执行第三方函数时,任何其他需要写入标准错误的线程也将写入/dev/null.

您可能不得不考虑添加一个“错误写入线程”(EWT),它可以与“第三方库执行线程”(TPLET)同步。其他线程会将消息写入 EWT。如果 TPLET 正在执行第三方库,则 EWT 将等到它完成,然后才写入任何排队的消息。 (虽然这会“工作”,但这是一项艰苦的工作。)

解决此问题的一种方法是让通用代码(第三方库代码除外)使用的错误报告函数写入fd2_copy而不是标准错误本身。这将需要严格使用错误报告功能,但比额外的线程更容易。

于 2013-05-30T07:03:24.183 回答
2

stderr是每个进程而不是每个线程,因此关闭它将关闭所有线程。

如果您想跳过特定消息,您可以使用grep -v.

于 2013-05-30T07:04:51.223 回答
2

在 Linux 上,可以unshare()使用以下声明的函数为当前线程提供自己的私有文件描述符表<sched.h>

unshare(CLONE_FILES);

在那次调用之后,你可以调用close(2);它,它只会影响当前线程。

但是请注意,一旦文件描述符表被取消共享,您就无法再次共享它 - 这是一种单向操作。这也是 Linux 特定的,因此它不是可移植的。

于 2013-05-30T07:38:17.883 回答