我是 pthread 同步的新手,在 google 中搜索了“pthread 條件變數”并從 pdf 中獲取了一個示例:https ://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf 。
示例代碼如下,其目的是“使用條件變數和變數done來實作pthread_join()”(據我了解):
// https://godbolt.org/z/8rPMq54K8
#include <stdio.h>
#include <pthread.h>
volatile int done = 0;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c = PTHREAD_COND_INITIALIZER;
void thr_exit() {
pthread_mutex_lock(&m);
done = 1;
pthread_cond_signal(&c);
pthread_mutex_unlock(&m);
}
void *child(void *arg) {
printf("child\n");
thr_exit();
return NULL;
}
void thr_join() {
pthread_mutex_lock(&m);
while (done == 0)
{
pthread_cond_wait(&c, &m);
}
pthread_mutex_unlock(&m);
}
int main(int argc, char *argv[])
{
printf("parent: begin\n");
pthread_t p;
pthread_create(&p, NULL, child, NULL);
thr_join();
printf("parent: end\n");
return 0;
}
編譯:
clang main.cpp -fsanitize=thread -g -fno-omit-frame-pointer
運行它會看到“執行緒泄漏”報告:
(base) ? case12 git:(main) ? ./a.out
a.out(71120,0x10433c580) malloc: nano zone abandoned due to inability to preallocate reserved vm space.
parent: begin
child
parent: end
==================
WARNING: ThreadSanitizer: thread leak (pid=71120)
Thread T1 (tid=1365892, finished) created by main thread at:
#0 pthread_create <null>:74364228 (libclang_rt.tsan_osx_dynamic.dylib:arm64e 0x2bbe8)
#1 main main_v4.cpp:31 (a.out:arm64 0x100003e38)
SUMMARY: ThreadSanitizer: thread leak main_v4.cpp:31 in main
==================
ThreadSanitizer: reported 1 warnings
這個 C 代碼真的是執行緒泄漏,還是只是來自 tsan 的誤報?
uj5u.com熱心網友回復:
這個 C 代碼真的是執行緒泄漏,還是只是來自 tsan 的誤報?
這實際上是執行緒泄漏,因為您無法實作pthread_join(). 至少,不是以任何可移植方式或僅基于 C (或 C)和 pthreads 規范。程式啟動一個執行緒,在終止之前既不分離也不加入它。那是執行緒泄漏。
該程式確實成功且可靠地等待終止,直到子執行緒提供它已呼叫的證據thr_exit(),但這不能替代加入子執行緒。
uj5u.com熱心網友回復:
(這不是答案,只是我在閱讀 John Bollinger 的答案后可以撰寫的解決方案代碼。)
解決方案1:
int main(int argc, char *argv[])
{
printf("parent: begin\n");
pthread_t p;
pthread_create(&p, NULL, child, NULL);
pthread_detach(p); // !! new added line
thr_join();
printf("parent: end\n");
return 0;
}
解決方案2:
void *child(void *arg) {
pthread_detach(pthread_self()); //!! new added line
printf("child\n");
thr_exit();
return NULL;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/482946.html
