问题描述:

I have a main thread which initializes few data structures and spawns a fixed number of threads. These threads use the data structures created in main thread and interact with database. When interacting with database server if server returns any error, the corresponding thread frees all the data structures initialized by main thread and invokes exit().

Since these data structures are commonly used by all threads, i have a problem of crash when there is a context switch to any other thread after freeing the data structure.

I have a solution to this problem: Make freeing and call to exit() as 1 single atomic operation. Will this work ?

Or is there any way to notify main thread when any of the child results in error, so that main thread can handle accordingly. I can't use condition variables as it is a blocking operation. I want my main thread to be non-blocking.

Below is the code snippet:

#include <iostream>

#include <boost/thread.hpp>

Connection_Handler *conn;

boost::thread_group g;

void talk_to_server()

{

int result= 0;

// read query from a batch file //

result= conn->execute(query);

if (result)

{

// making below 2 statements as atomic solve my problem ?

delete conn;

exit();

}

}

int main(int argc, char* argv[])

{

conn = new Connection_Handler();

// launch three threads

boost::thread *t1 = new boost::thread(talk_to_server);

boost::thread *t2 = new boost::thread(talk_to_server);

boost::thread *t3 = new boost::thread(talk_to_server);

g.add_thread(&t1);

g.add_thread(&t2);

g.add_thread(&t3);

// wait for them

g.join_all();

return 0;

}

网友答案:

The simple answer is that the owner of the Connection_Handler() object is the Main Thread, and thus it should be the Main thread to dispose of the object, not a child thread. Moreover, the child thread should 'return()' instead of 'exit()', so that the Main Thread is given a chance to dispose of it.

If the Main Thread needs to be non-blocking it means that it contains some other programming logic that does not pertain handling the life-cycle of the children threads. Therefore [from a Software Engineering point of view] my suggestion is to separate these two tasks and split the Main Thread into two, simpler, threads: one for other core-activities and the other for handling threads. In this way you can make the thread-handler wait on a condition variable, or a child-thread death, and perform appropriate cleaning of the resources before exiting.

For info on how to use Boost's condition variables see, e.g., How do I use a boost condition variable to wait for a thread to complete processing? or Have main thread wait for a boost thread complete a task (but not finish).

Just my two cents.

相关阅读:
Top