Write two threads at the same time

Is there a way to link two streams (or file descriptors) together so that a write to one stream is also written to the second? (C, Linux)

Thanks.

+5
source share
5 answers

The user laalto is right, but on Linux, the function you are looking for is called fopencookie . Fixing the laalto example for Linux results in:

 int my_writefn(void *cookie, const char *data, int n) { FILE **files = (FILE **)cookie; fwrite(data, n, 1, files[0]); return fwrite(data, n, 1, files[1]); } int noop(void) { return 0; } cookie_io_functions_t my_fns = { (void*) noop, (void*) my_writefn, (void*) noop, (void*) noop }; FILE *files[2] = ...; FILE *f = fopencookie((void *)files, "w", my_fns); // ... use f as you like ... 

When you write to f , the system will execute your function my_writefn , passing it the data that was passed to fwrite . To simplify the task, you can also change the buffering for the line-oriented file stream:

 setvbuf(f, NULL, _IOLBF, 0); 

This will buffer the data passed to fwrite until a new line is output, or any data is read from any process-related stream (e.g. stdin). NOTE: you must call sevbuf after fopencookie , but before writing any data to the stream.

I use line buffering because I usually use fopencookie to redirect stderr to syslog or through a network socket, and the processing-oriented data is simpler and more efficient.

+1
source

Use funopen or fwopen and put your own write function, which writes to multiple FILE* s.

Example:

 FILE *files[2] = ...; FILE *f = fwopen((void *)files, my_writefn); // ... use f as you like ... int my_writefn(void *cookie, const char *data, int n) { FILE **files = (FILE **)cookie; fwrite(data, n, 1, files[0]); return fwrite(data, n, 1, files[1]); } 

(Error handling omitted.)

Note that funopen and fwopen are BSD, not standard Linux. I do not know if there is a Linux compatible equivalent.

+6
source

The first thing that occurred to me was also the "tee." So let me combine C and shell with popen:

 FILE * multi_out; multi_out = popen( "tee file1.out > file2.out", "w"); /* error checks, actual work here */ pclose( multi_out); /* error checks here */ 

As a Unix fanatic, I suggested that you are not trying to do this on Windows.

+4
source

Not sure if this is what you want, but tee on unix does something similar.

+2
source

You can implement something similar to tee functionality with boost :: iostreams .

+1
source

Source: https://habr.com/ru/post/913748/


All Articles