gpt4 book ai didi

c - 如何等待启动线程执行初始化代码

转载 作者:太空狗 更新时间:2023-10-29 15:16:37 26 4
gpt4 key购买 nike

我在将主线程同步到最近启动的子线程时遇到问题。

我想做的是:

  • 主线程创建一个新的子线程并阻塞
  • 子线程启动并初始化(可能需要一些时间)
  • 一旦子线程被初始化,主线程继续(两个线程并行运行)

我的第一次尝试是这样的:

  typedef struct threaddata_ {
int running;
} threaddata_t;

void*child_thread(void*arg) {
threaddata_t*x=(threaddata_t)arg;
/* ... INITIALIZE ... */
x->running=1; /* signal that we are running */

/* CHILD THREAD BODY */

return 0;
}

void start_thread(void) {
threaddata_t*x=(threaddata_t*)malloc(sizeof(threaddata_t));
x->running=0;
int result=pthread_create(&threadid, 0, child_thread, &running);
while(!x->running) usleep(100); /* wait till child is initialized */

/* MAIN THREAD BODY */
}

现在我一点都不喜欢这个,因为它迫使主线程休眠的时间可能比必要的时间更长。所以我做了第二次尝试,使用互斥锁和条件

  typedef struct threaddata_ {
pthread_mutex_t x_mutex;
pthread_cond_t x_cond;
} threaddata_t;

void*child_thread(void*arg) {
threaddata_t*x=(threaddata_t)arg;
/* ... INITIALIZE ... */

pthread_cond_signal(&x->x_cond); /* signal that we are running */

/* CHILD THREAD BODY */

return 0;
}

void start_thread(void) {
threaddata_t*x=(threaddata_t*)malloc(sizeof(threaddata_t));
pthread_mutex_init(&x->x_mutex, 0);
pthread_cond_init (&x->x_cond , 0);

pthread_mutex_lock(&x->x_mutex);
int result=pthread_create(&threadid, 0, child_thread, &running);
if(!result)pthread_cond_wait(&x->x_cond, &x->x_mutex);
pthread_mutex_unlock(&x->x_mutex);

/* MAIN THREAD BODY */
}

这似乎比第一次尝试更理智(使用适当的信号而不是滚动我自己的等待循环),直到我发现,这包括一个竞争条件: 如果子线程足够快地完成初始化(在主线程等待条件之前),它就会死锁主线程。

我想我的情况并不少见,所以一定有一个非常简单的解决方案,但我现在看不到。

最佳答案

condvar/mutex 对使用的正确方法:

bool initialised = false;
mutex mt;
convar cv;

void *thread_proc(void *)
{
...
mt.lock();
initialised = true;
cv.signal();
mt.unlock();
}

int main()
{
...
mt.lock();
while(!initialised) cv.wait(mt);
mt.unlock();
}

该算法避免了任何可能的竞争。您可以使用互斥锁定时修改的任何复杂条件(而不是简单的 !initialised)。

关于c - 如何等待启动线程执行初始化代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11471930/

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