每个 POSIX 线程有不同的标准流

发布于 2024-09-02 01:02:15 字数 768 浏览 6 评论 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;
}

Is there any possibility to achieve different redirections for standard output like printf(3) for different POSIX thread? What about standard input?

I have lot of code based on standard input/output and I only can separate this code into different POSIX thread, not process. Linux operation system, C standard library.
I know I can refactor code to replace printf() to fprintf() and further in this style.
But in this case I need to provide some kind of context which old code doesn't have.

So doesn't anybody have better idea (look into code below)?

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

早乙女 2024-09-09 01:02:15

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

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

You can do what you want if you create threads using clone, but POSIX.1 says that the threads must share open file discriptors.

There are several tricks you could try, but you really should just convert the calls to the FILE * argument accepting functions.

懒猫 2024-09-09 01:02:15

在 *nix 系统上,stdio 位于文件描述符之上,并且文件描述符对于进程来说是全局的。因此,如果不改变某些东西,就无法做你想做的事。最好的选择是使用 fprintf() 重写代码。由于这涉及向 arglist 添加参数,我什至不确定您是否能够使用预处理器技巧来实现您的目标而不修改实际代码。

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

On *nix systems, stdio layers over file descriptors, and file descriptors are global to a process. Thus, there is no way to do what you want without changing something. Your best bet is to rewrite code using fprintf(). Since this involves adding an argument to an arglist, I'm not even sure that you'd be able to use preprocessor trickery to achieve your goals without modifying the actual code.

Maybe you could clarify the reasons that you can't create new processes? The problem may be solvable from that angle.

南烟 2024-09-09 01:02:15

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

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

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

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

If you have thread-local storage, you could do something like:

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

and likewise for all the other stdio functions you intend to use. Of course it would be better not to try redefining the same names, but instead perform search and replace on the source files to use alternate names.

BTW even without thread-local storage extensions to the compiler, you could use a function call that returns the right FILE * for the calling thread to use.

阳光下慵懒的猫 2024-09-09 01:02:15

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

If you insist on using the standard I/O functions like "printf()" then the only way I can think of that this could be done is for the standard I/O library to support thread-specific I/O using thread-local data structures (similar to the way "errno" is a macro that calls a function that returns the thread-local error number). I don't know of any implementations of standard I/O that do this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文