The following code provides an example of a multiply-threaded application that uses iostream objects from the libC library in an MT-safe way.
The example application creates up to 255 threads. Each thread reads a different input file, one line at a time, and outputs the line to an output file, using the standard output stream, cout. The output file, which is shared by all threads, is tagged with a value that indicates which thread performed the output operation.
// create tagged thread data
// the output file is of the form:
// <tag><string of data>\n
// where tag is an integer value in a unsigned char.
// Allows up to 255 threads to be run in this application
// <string of data> is any printable characters
// Because tag is an integer value written as char,
// you need to use od to look at the output file, suggest:
// od -c out.file |more
#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>
#include <fstream.h>
#include <thread.h>
struct thread_args {
char* filename;
int thread_tag;
};
const int thread_bufsize = 256;
// entry routine for each thread
void* ThreadDuties(void* v) {
// obtain arguments for this thread
thread_args* tt = (thread_args*)v;
char ibuf[thread_bufsize];
// open thread input file
ifstream instr(tt->filename);
stream_locker lockout(cout, stream_locker::lock_defer);
while(1) {
// read a line at a time
instr.getline(ibuf, thread_bufsize - 1, ’\n’);
if(instr.eof())
break;
// lock cout stream so the i/o operation is atomic
lockout.lock();
// tag line and send to cout
cout << (unsigned char)tt->thread_tag << ibuf << "\n";
lockout.unlock();
}
return 0;
}
int main(int argc, char** argv) {
// argv: 1+ list of filenames per thread
if(argc < 2) {
cout << “usage: " << argv[0] << " <files..>\n";
exit(1);
}
int num_threads = argc - 1;
int total_tags = 0;
// array of thread_ids
thread_t created_threads[thread_bufsize];
// array of arguments to thread entry routine
thread_args thr_args[thread_bufsize];
int i;
for(i = 0; i < num_threads; i++) {
thr_args[i].filename = argv[1 + i];
// assign a tag to a thread - a value less than 256
thr_args[i].thread_tag = total_tags++;
// create threads
thr_create(0, 0, ThreadDuties, &thr_args[i],
THR_SUSPENDED, &created_threads[i]);
}
for(i = 0; i < num_threads; i++) {
thr_continue(created_threads[i]);
}
for(i = 0; i < num_threads; i++) {
thr_join(created_threads[i], 0, 0);
}
return 0;
}
|