0

是否有可能为不同的 POSIX 线程实现不同的标准输出重定向,如 printf(3)?标准输入呢?

我有很多基于标准输入/输出的代码,我只能将这些代码分成不同的 POSIX 线程,而不是进程。Linux操作系统,C标准库。我知道我可以重构代码以将 printf() 替换为 fprintf() 并进一步采用这种风格。但在这种情况下,我需要提供某种旧代码所没有的上下文。

那么没有人有更好的主意(查看下面的代码)吗?

#include <pthread.h>
#include <stdio.h>

void* different_thread(void*)
{
    // Something to redirect standard output which doesn't affect main thread.
    // ...

    // printf() shall go to different stream.
    printf("subthread test\n");

    return NULL;
}

int main()
{
    pthread_t id;
    pthread_create(&id, NULL, different_thread, NULL);

    // In main thread things should be printed normally...
    printf("main thread test\n");

    pthread_join(id, NULL);
    return 0;
}
4

4 回答 4

4

如果您使用创建线程,您可以做您想做的事clone,但 POSIX.1 说线程必须共享打开的文件描述符。

您可以尝试几种技巧,但您确实应该将调用转换为FILE *接受参数的函数。

于 2010-05-19T18:24:51.383 回答
1

如果您有线程本地存储,则可以执行以下操作:

#undef printf
#define printf(fmt, ...) fprintf(my_threadlocal_stdout, fmt, __VA_ARGS__)

同样适用于您打算使用的所有其他 stdio 功能。当然,最好不要尝试重新定义相同的名称,而是对源文件执行搜索和替换以使用替代名称。

顺便说一句,即使没有对编译器进行线程本地存储扩展,您也可以使用一个函数调用来返回FILE *调用线程使用的权限。

于 2010-07-26T12:23:59.450 回答
1

在 *nix 系统上,文件描述符上的 stdio 层和文件描述符对于进程是全局的。因此,如果不更改某些内容,就无法做你想做的。最好的办法是使用 fprintf() 重写代码。由于这涉及向 arglist 添加参数,我什至不确定您是否能够在不修改实际代码的情况下使用预处理器技巧来实现目标。

也许您可以澄清您无法创建新流程的原因?这个问题或许可以从这个角度解决。

于 2010-05-19T18:29:44.633 回答
0

如果您坚持使用像“printf()”这样的标准 I/O 函数,那么我能想到的唯一方法是让标准 I/O 库使用线程本地支持线程特定的 I/O数据结构(类似于“errno”是一个宏,它调用一个返回线程本地错误号的函数)。我不知道执行此操作的标准 I/O 的任何实现。

于 2010-05-19T18:14:05.007 回答