具有互斥量和信号量的多线程程序
multithread program with mutexes and semapohres
有 3 个系列要使用多线程计算。
要访问一个系列,您需要等待信号量,然后您需要知道您是构建线程还是清理线程。
当我有 num 个线程,所有线程都可以执行操作并且没有 'floating' 线程无法访问信号量或互斥锁时,一切都很好。
如果我确实有太多线程并且没有什么可做的程序就会卡住,除非在 WaitSemRes/WaitMutexRes 之后我杀死那个线程但我不想这样做因为我失去了很多计算时间。
我只是想让他们一直等到他们有事做。
我错过了什么吗?
/* Thread is trying to enter specific series, if couldnt - try the next one*/
WaitSemRes = WaitForSingleObject(main_series[series_idx].semaphore, 0L);
if (WaitSemRes == WAIT_OBJECT_0) {
/* Check if i'm the cleaning thread */
if (main_series[series_idx].ready_to_clean) {
/* Catching series mutex to clean it alone */
WaitMutexRes = WaitForSingleObject(main_series[series_idx].mutex, INFINITE);
if (WaitMutexRes == WAIT_OBJECT_0)
// do something //
}
else {
ExitThread(0);
}
// do stuff
else {
ExitThread(0);
}
您可以使用 关闭事件 在没有更多工作要做时向线程发出信号,这样它们就可以无限期地等待。它可以使用 CreateEvent 创建,然后您需要做的就是让您的工作线程等待它。完成所有工作后,您可以使用 SetEvent 使所有线程几乎同时退出,然后等待包含所有线程句柄的 HANDLE 数组
有关如何等待多个对象的详细信息,您可以参考WaitForMultipleObjects Example
工作线程
int thread_function(...) {
[...]
while(WaitForSingleObject(thread_shutdown_event, 0) != WAIT_OBJECT_0) {
// Keep trying to process data until the event is signalized
}
// Exit thread
return 0;
}
池处理函数
void end_thread_pool(...) {
HANDLE wait_result;
if(thread_shutdown_event == NULL)
return;
// Activate shutdown event
SetEvent(thread_shutdown_event);
// Wait upon thread handle list until all threads can return safely
wait_result = (HANDLE)WaitForMultipleObjects(...);
if(wait_result != WAIT_OBJECT_0) {
// Failed to wait
}
CloseHandle(thread_shutdown_event);
[...]
return;
}
void init_thread_pool(...) {
[...]
thread_shutdown_event = CreateEvent(NULL, // Default security attributes
TRUE, // Manual reset?
FALSE,// Starting value
TEXT("Thread Shutdown event"));// Event name
if(thread_shutdown_event == NULL) {
// Failed to create event
return;
}
// Initiates threads and also puts their HANDLEs in a array
// that is going to be used in end_thread_pool to wait
// See 'WaitForMultipleObjects Example'
thread_create(thread_function, number_of_threads);
[...]
return;
}
有 3 个系列要使用多线程计算。
要访问一个系列,您需要等待信号量,然后您需要知道您是构建线程还是清理线程。
当我有 num 个线程,所有线程都可以执行操作并且没有 'floating' 线程无法访问信号量或互斥锁时,一切都很好。
如果我确实有太多线程并且没有什么可做的程序就会卡住,除非在 WaitSemRes/WaitMutexRes 之后我杀死那个线程但我不想这样做因为我失去了很多计算时间。
我只是想让他们一直等到他们有事做。
我错过了什么吗?
/* Thread is trying to enter specific series, if couldnt - try the next one*/
WaitSemRes = WaitForSingleObject(main_series[series_idx].semaphore, 0L);
if (WaitSemRes == WAIT_OBJECT_0) {
/* Check if i'm the cleaning thread */
if (main_series[series_idx].ready_to_clean) {
/* Catching series mutex to clean it alone */
WaitMutexRes = WaitForSingleObject(main_series[series_idx].mutex, INFINITE);
if (WaitMutexRes == WAIT_OBJECT_0)
// do something //
}
else {
ExitThread(0);
}
// do stuff
else {
ExitThread(0);
}
您可以使用 关闭事件 在没有更多工作要做时向线程发出信号,这样它们就可以无限期地等待。它可以使用 CreateEvent 创建,然后您需要做的就是让您的工作线程等待它。完成所有工作后,您可以使用 SetEvent 使所有线程几乎同时退出,然后等待包含所有线程句柄的 HANDLE 数组
有关如何等待多个对象的详细信息,您可以参考WaitForMultipleObjects Example
工作线程
int thread_function(...) {
[...]
while(WaitForSingleObject(thread_shutdown_event, 0) != WAIT_OBJECT_0) {
// Keep trying to process data until the event is signalized
}
// Exit thread
return 0;
}
池处理函数
void end_thread_pool(...) {
HANDLE wait_result;
if(thread_shutdown_event == NULL)
return;
// Activate shutdown event
SetEvent(thread_shutdown_event);
// Wait upon thread handle list until all threads can return safely
wait_result = (HANDLE)WaitForMultipleObjects(...);
if(wait_result != WAIT_OBJECT_0) {
// Failed to wait
}
CloseHandle(thread_shutdown_event);
[...]
return;
}
void init_thread_pool(...) {
[...]
thread_shutdown_event = CreateEvent(NULL, // Default security attributes
TRUE, // Manual reset?
FALSE,// Starting value
TEXT("Thread Shutdown event"));// Event name
if(thread_shutdown_event == NULL) {
// Failed to create event
return;
}
// Initiates threads and also puts their HANDLEs in a array
// that is going to be used in end_thread_pool to wait
// See 'WaitForMultipleObjects Example'
thread_create(thread_function, number_of_threads);
[...]
return;
}