1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | uint32_t thread_queue_work( thread_queue_t* queue, ... ) { uint32_t result = 0; ... ReleaseSemaphore( queue->semaphore, 1, 0 ); ... return result; } DWORD thread_main( void* thread_data ) { thread_queue_t* queue = ( thread_queue_t* ) thread_data; while ( !queue->terminate ) { if ( !thread_do_work( queue ) ) { WaitForSingleObjectEx( queue->semaphore, INFINITE, 0 ); } } return 0; } void thread_complete_queue( thread_queue_t* queue ) { while ( queue->completion_count != queue->completion_goal ) { thread_do_work( queue ); } } int main( int argc, char** argv ) { thread_queue_t queue = thread_queue_init( ); thread_queue_work( &queue, ... ); thread_queue_work( &queue, ... ); thread_complete_queue( &queue ); thread_queue_work( &queue, ... ); thread_queue_work( &queue, ... ); thread_complete_queue( &queue ); return 0; } |
But if there is only two tasks to do and they take some time, thread_complete_queue is mostly a busy loop which I would like to avoid. Also not all program will use thread_complete_queue, so the thread must not do something that would fail if thread_complete_queue is not called.
Is there a good way to do this ? Is it possible to wait for the semaphore to "be 0" ? Should I use CreateEvent to create an event for each thread and use WaitForMultipleObjects ? Would that work if thread_complete_queue isn't called ? Would it work if I have several hundred threads ?