Blue7 Blue7 - 2 years ago 58
C++ Question

How to print to standard output from multiple threads using POCO in c++

I want to create a simple program that starts 5 threads that print "hello world! This is thread [thread number]".

Each print operation should be preceded by a random wait operation, to demonstrate that the threads are running concurrently. (The threads will print their message in a random order, as opposed to printing in order which would happen if the threads are running sequentially.)

Here is the code that should achieve this:

Poco::Thread thread[5];

class HelloRunnable: public Poco::Runnable
{
public:
HelloRunnable(int arg)
{
n = arg;
}

int n;

virtual void run()
{
usleep(rand()%100000);
std::cout << "Hello, world! This is thread " << n << std::endl;
}
};

int main()
{
for(int i=0; i<5; i++)
{
HelloRunnable runnable(i);
thread[i].start(runnable);
}

for(int i=0; i<5; i++)
{
thread[i].join();
}
return 0;
}


However, at run time, this gives the error:

//pure virtual method called
//terminate called without an active exception
//The program has unexpectedly finished.


If instead, I put
thread[i].join()
inside the same for loop as
thread[i].start()
, then the program runs without error but it prints the threads in order. (Becuase
join()
waits until the thread has finished before moving on, hence the threads are executed sequentially and not concurrently.

How can I make the threads run concurrently and print out the message to the standard output as soon as
cout
is called?

Answer Source

Since you create the objects inside the for loop their lifetime will end immediately after each iteration. This will cause issues. As the documentation for start() states:

Note that the given Runnable object must remain valid during the entire lifetime of the thread, as only a reference to it is stored internally.

You need to create the runnables in a way that keeps them alive outside the loop also.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download