在multithreading应用程序中,如何将stderr和stdoutredirect到每个线程的单独文件中?

我有multithreading应用程序中,即时通讯创build这样的线程

int main(int argc,char *argv[]) { pthread_t thread_id[argc-1]; int i; struct parameter thread_data[argc-1]; int status; for(i=0;i<argc-1;i++) { thread_data[i].ip_filename = argv[i+1]; strcpy (thread_data[i].op_filename,argv[i+1]); strcat (thread_data[i].op_filename,".h264"); } for(i=0;i<argc-1;i++) { pthread_create (&thread_id[i], NULL , &thread_function, &thread_data[i]); } } 

现在在线程function

我想在每个线程中将stderr和stdoutredirect到一个单独的文件中

有些像线程日志文件

我怎么能这样做?

编辑:

如果线程特定的打印可以显示在不同的terminal..? 我的意思是如果有2线程然后打开2terminal和打印每个线程数据在不同的terminal

Solutions Collecting From Web of "在multithreading应用程序中,如何将stderr和stdoutredirect到每个线程的单独文件中?"

如果你真的必须这样做…

首先,您需要创建2个pthread_key_t ,一个用于stdout ,另一个用于stderr 。 这些可以使用pthread_key_create创建,并且必须可以从所有线程访问。 我们称它们为stdout_keystderr_key

当一个线程被创建时:

 FILE *err = ..., *out = ...; pthread_setspecific(stdout_key, out); pthread_setspecific(stderr_key, err); 

然后在你的头文件中:

 #define stdout (FILE*)pthread_getspecific(stdout_key) #define stderr (FILE*)pthread_getspecific(stderr_key) #define printf(...) fprintf(stdout, ##__VA_ARGS__) 

那么只需使用:

 fprintf(stderr, "hello\n"); fprintf(stdout, "hello\n"); printf("hello\n"); 

我不推荐这种方法。

我不认为这是可能的。 stdin / stdout是全局变量,在线程之间共享,文件描述符也是如此。

您将不得不创建自己的文件,并将printf更改为fprintf

根据定义, stdoutstderr是唯一的流。 想象一下,如果有多个stdout ,shell如何重定向你的流? 您需要创建自己的输出流/文件变量,然后使用它们。 这有什么问题吗?

您可能会发现使用特定于线程的存储很有用。


你不能让一个进程在不同的终端上输出一些东西。 这个过程不知道终端,它只是输出流, 终端拿起来显示。

但是,你可以做的是将一个流的输出引导到一个文件中,然后在另一个终端中运行tail -f <filename>

你将不得不跟踪每个线程使用什么FILE* / fd并使用fprintf等。没有其他办法。

对于多个终端,您需要在程序中打开每个终端。 没有办法自动找出哪一个打开。 在要打开的终端的shell中运行/bin/tty ,然后在程序中打开该终端。

另一种方法是让一个AF_UNIX套接字监听连接。 然后你写一个单独的程序连接到该套接字。 您可以在希望输出的终端上运行该程序。

我在线程中使用fork()来重定向分叉进程的stdout,而“true”线程在waitpid() 。 问题是如何将文件传递到要重定向stdout的位置。 我使用全局线程池,线程将通过pthread_equal(pthread_self(),iterator)找到自己,然后在全局线程池结构中有程序应该重定向stdout的outfile。 在我的情况下,我创建一个tmpnam()并将其写入线程结构,但您可以使用它的方式。

下面是一些示例代码:(写在飞行中)

 pthread_t *t_cur=NULL; int i,pid,newout; char *outfile=NULL; for(i=0;i<MAX_THREADS;i++) if(pthread_equal(pthread_self(),globals.tpool[i]->thread)) break; if(i==MAX_THREADS) { printf("cannot find myself into global threads pool.\n"); pthread_exit(&i); } if(globals.tpool[i]->outfile == NULL) // redirect stdout only if outfile is not set ( this is specfic for my purposes ) { outfile = globals.tpool[i]->outfile = malloc(L_tmpnam*sizeof(char)); tmpnam(outfile); } if((pid = fork()) == 0) { if(outfile!=NULL) { newout = open(outfile,O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); dup2(newout,STDOUT_FILENO); close(newout); } /* your code here */ } else waitpid(pid,NULL); pthread_exit(&i); 

我真的写了它,我没有测试这个代码,所以要小心修复任何错误。 我没有发布我的真实代码,因为对我自己的图书馆的电话。 这里我没有检查tmpnam()fork()open()malloc()的返回值,你应该这样做。