假设我的程序有一些线程,因为文件描述符在线程之间共享,如果我调用close(stderr)
,所有线程都不会输出到stderr
。我的问题:有没有办法在一个线程中关闭stderr
的输出,而不是其他线程的输出?
更具体地说,我的程序的一个线程调用第三方库函数,它保持输出警告消息,我知道这些消息是无用的。但我无法访问此第三方库源。
答案 0 :(得分: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
而不是标准错误本身。这需要严格使用错误报告功能,但比额外的线程更容易整个堆。
答案 1 :(得分:2)
stderr
是每个进程而不是每个线程,因此关闭它将关闭所有线程。
如果您想跳过特定消息,可以使用grep -v
。
答案 2 :(得分:2)
在Linux上, 可以使用unshare()
中声明的<sched.h>
函数为当前线程提供自己的私有文件描述符表:
unshare(CLONE_FILES);
在通话结束后,您可以拨打close(2);
,它只会影响当前主题。
但请注意,一旦文件描述符表未被共享,您就无法再返回共享它 - 这是一个单向操作。这也是特定于Linux的,所以它不可移植。