gpt4 book ai didi

c++ - pthread_cond_wait : random segmentation fault

转载 作者:行者123 更新时间:2023-11-28 07:59:43 25 4
gpt4 key购买 nike

更新3

最近,我注意到我的代码随机导致Segmentation Fault 错误。但我认为到目前为止我的代码非常简单,我无法弄清楚错误的来源。由于它是随机发生的,我假设存在某种竞争条件。我认为这是所有可能相关的代码,如果您需要更多,请告诉我:

namespace thread {
pthread_t terminated_thread_id, /* and others */;
pthread_mutex_t terminate_thread = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t terminate_thread_signal = PTHREAD_COND_INITIALIZER;
int total_thread_count = 0;
int termination; // + sembufs

inline void* Exit(void* value) {
// This must be unlocked after all join-related jobs are done
semop(thread::termination, thread::termination_in_process, 2)
pthread_mutex_lock(&thread::terminate_thread);
thread::terminated_thread_id = pthread_self();
pthread_cond_signal(&thread::terminate_thread_signal);
pthread_mutex_unlock(&thread::terminate_thread);

pthread_exit(value);
return value;
}
}
int main(int argc, const char** argv){
...
pthread_mutex_lock(&thread::terminate_thread);
if(0 != pthread_create(&thread::communication_handler_thread_id, NULL, \
CommunicationHandler, NULL)){
global::PrintDebug("pthread_create() failed", __FILE__, __LINE__);
}
/** 2 more pthread_create()-calls */
do{
thread::terminated_thread_id = pthread_self();
pthread_cond_wait(&thread::terminate_thread_signal, \
&thread::terminate_thread);
if(!pthread_equal(thread::terminated_thread_id, pthread_self())){
pthread_join(thread::terminated_thread_id, NULL);
...
semop(thread::termination, thread::termination_done, 1)
}
}while(thread::total_thread_count > 0);

pthread_mutex_unlock(&thread::terminate_thread);
return 0;
}

terminate_thread_signal 信号仅在 thread::Exit() 函数中发出。该函数也仅在用于创建线程的函数末尾调用。

这是调试器为调用堆栈显示的内容:

#0 (    0xb7fe2424 in __kernel_vsyscall() (??:??)
#1 0xb7fbdfcf __pthread_cond_wait(cond=0x80539c0, mutex=0x8053998) (pthread_cond_wait.c:153)
#2 0x804a094 main(argc=1, argv=0xbffff9c4) (/home/papergay/SeekYourCar/0.2/Server/main.cpp:121)

我已经知道的是,如果发生错误,则说明还没有线程调用 thread::Exit()。我还使用了一个未命名的命名空间和一些初始化(如果可能相关的话)。我使用 Code::Blocks 作为 IDE,使用 GCC 作为编译器。

最佳答案

pthread_cond_wait() 允许虚假唤醒,因此您必须在每次唤醒后重新测试条件本身。这可能会导致您的问题 - 如果主线程在设置 thread::terminated_thread_id 之前虚假地唤醒,它会将无效的线程 ID 传递给 pthread_join()

您的代码中还有另一个问题 - 无法保证在互斥量解锁后,已发出信号的线程将是下一个被唤醒的线程,因此两个线程可能会调用 thread::Exit() 快速连续,主线程直到第二个退出线程解锁互斥锁后才运行。在这种情况下,您永远不会在第一个线程上调用 pthread_join()

像这样应该可以解决这些问题:

namespace thread {
int terminate_thread_set = 0;
pthread_mutex_t terminate_thread = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t terminate_thread_set_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t terminate_thread_unset_cond = PTHREAD_COND_INITIALIZER;

/* ... */

inline void Exit(void* value)
{
pthread_mutex_lock(&thread::terminate_thread);
while (thread::terminate_thread_set)
pthread_cond_wait(&thread::terminate_thread_unset_cond);
thread::terminated_thread_id = pthread_self();
thread::terminate_thread_set = 1;
pthread_cond_signal(&thread::terminate_thread_set_cond);
pthread_mutex_unlock(&thread::terminate_thread);

pthread_exit(value);
}
}

main 中:

pthread_mutex_lock(&thread::terminate_thread);

/* ... */

while(thread::total_thread_count > 0) {
while (!thread::terminate_thread_set)
pthread_cond_wait(&thread::terminate_thread_set_cond, &thread::terminate_thread);
thread::terminate_thread_set = 0;
pthread_join(thread::terminated_thread_id, NULL);
pthread_cond_signal(&thread::terminate_thread_unset_cond);
...
}
pthread_mutex_unlock(&thread::terminate_thread);

当然,这并不是说您没有其他问题。

关于c++ - pthread_cond_wait : random segmentation fault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11816284/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com