views:

473

answers:

2

Hi,

I am migrating an applciation from windows to linux. I am facing problem w.r.t WaitForSingleObject and WaitForMultipleObjects interfaces

In my application I spawn multiple threads where all threads wait for events from parent process or periodically run for every t seconds.

How can I implement this in Unix.

I have checked pthread_cond_timedwait, but we have to specify absolute time for this.

+1  A: 

Stick to pthread_cond_timedwait and use clock_gettime. For example:

struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 10; // ten seconds
while (!some_condition && ret == 0)
    ret = pthread_cond_timedwait(&cond, &mutex, &ts);

Wrap it in a function if you wish.


UPDATE: complementing the answer based on our comments.

POSIX doesn't have a single API to wait for "all types" of events/objects as Windows does. Each one has its own functions. The simplest way to notify a thread for termination is using atomic variables/operations. For example:

Main thread:

// Declare it globally (argh!) or pass by argument when the thread is created
atomic_t must_terminate = ATOMIC_INIT(0);

// "Signal" termination by changing the initial value
atomic_inc(&must_terminate); 

Secondary thread:

// While it holds the default value
while (atomic_read(&must_terminate) == 0) {
    // Keep it running...
}
// Do proper cleanup, if needed
// Call pthread_exit() providing the exit status

Another alternative is to send a cancellation request using pthread_cancel. The thread being cancelled must have called pthread_cleanup_push to register any necessary cleanup handler. These handlers are invoked in the reverse order they were registered. Never call pthread_exit from a cleanup handler, because it's undefined behaviour. The exit status of a cancelled thread is PTHREAD_CANCELED. If you opt for this alternative, I recommend you to read mainly about cancellation points and types.

And last but not least, calling pthread_join will make the current thread block until the thread passed by argument terminates. As bonus, you'll get the thread's exit status.

jweyrich
@jweyrich But is it mandatory on cond signal for threads which are waiting for the signal to lock the mutex and check the condition variable even if they are not contending for any resource.
siri
@Sirish POSIX doesn't have a single API to wait for "all types" of events/objects. Each one has its own functions. If you specify the type of event you're interested in, I might be able to indicate the most suitable API.
jweyrich
@jweyrich In my application I want each thread spawned by parent thread to wait for terminate event from parent and do some cleanup on terminate and parent to wait untill all spawned threads are terminated
siri
@Sirish What do you mean by `terminate event`? An atomic variable shared by all threads? Or you want a suggestion from me? For the parent-wait-threads part, you can sequentially call `pthread_join` for each thread you wish to wait.
jweyrich
@Sirish I gotta go now, but my suggestion for the `terminate event` without locking, is an atomic variable, or `pthread_cancel`+ `pthread_cleanup_push`. The first sends a cancellation request to the desired thread, and the second registers cleanup callbacks, and must be invoked by the thread itself. The cleanup callbacks will be invoked upon a cancellation request. I recommend you to read more on this subject, mainly cancellation points and types. Hopefully, this will answer your question(s).
jweyrich
I'll edit my answer later (when I get free time) to include all these informations.
jweyrich
A: 

A more Unix-y approach may be to fork instead of thread (call fork enough times so you have enough children), and use waitpid to wait for child processes. You can use waitpid to check the status of all children or specific children, and you can use any suitable sleep function (sleep, usleep etc) to get the timeout part of WaitForSingleObject. You can kill any child by using the kill function.

The child created by fork could just call the same function that's passed to CreateThread (or the pthread equivalent).

dreamlax
@dreamlax but I have many resources between child threads which if i convert to process will be difficult to implement
siri