pthreads - 停止当前执行的线程并在特定事件后重新启动它们

时间:2011-06-22 07:53:29

标签: c pthreads

我正在做一个关于VoIP的项目,我的C代码中有pthreads。我需要启动pthreads并使它们在它们之间有一些睡眠。现在我的线程正在运行,当我从服务器获得会话结束时,我需要停止正在运行的线程并从头开始重新启动它们。

我的代码看起来像这样:

void *recv_thread(void *arg)
{
/*receive the multimedia data and close the recv_thread when there is no more data to receive*/
}


void *send_thread(void *arg)
{
/*send the multimedia data*/
}

send_recv_data()
{

pthread_create(thread2, NULL, send_thread, NULL);
pthread_create(thread3, NULL, recv_thread, NULL);
}

void *first_thread(void *arg)
{
/*if some condition met the start the routine for creation of two threads one for receiving and one for sending data*/
if(cond == TRUE){
send_recv_data();
}

}
main()
{
pthread_create(thread1, NULL, first_thread, NULL);
}

我的问题是,一旦我收到来自其他用户代理的消息,它不再向我发送数据,那么我需要停止发送和recv线程,然后最后是first_thread,它负责创建另外两个线程。一旦我停止所有线程,我需要重新启动它们。我尝试使用互斥锁和条件变量,但都失败了。

任何关于如何克服这一点的想法,可能只是一小段简单的代码会更有帮助

谢谢

2 个答案:

答案 0 :(得分:4)

为什么需要启动和停止线程?保持线程运行通常更好,并且当它们没有任何有用的工作时阻止它们(例如条件变量)。

答案 1 :(得分:1)

我将做一些假设,因为正如比我更有知识的人所指出的,这种行为立即引发了为什么你(想你)需要摧毁/的问题重新创建这些线程,以及为什么这样做是模糊的:

  • 您有正当理由需要销毁/重新创建线程
  • 您有充分的理由将这许多可能无用的图层添加到线程创建过程中
  • 将“从其他用户代理接收消息”的代码可以访问线程ID
  • 您的sendrecv函数可以访问某种标记机制

这是一种鞋角方式,我几乎不敢接近它。如果不了解设计的约束,就很难表达出可以开始探索的一些选项。

首先,让我们设置sendrecv函数,以便通知他们是时候再见:

void* send_thread(void *arg)
{
    pthread_mutex_lock(&wrapUpFlagMutex);
    bool timeToQuit = wrapUpFlag;
    pthread_mutex_unlock(&wrapUpFlagMutex);

    while( timeToQuit == false )
    {
        ...
        // You're doing something here
        ...
        pthread_mutex_lock(&wrapUpFlagMutex);
        timeToQuit = wrapUpFlag;
        pthread_mutex_unlock(&wrapUpFlagMutex);
    }

    // We've been flagged! Get out...the join will catch us.
    pthread_exit();
}

现在更改代码,以某种方式知道魔法需要何时结束并重新启动:

dontShootTheMessenger()
{
    ...
    // We've just determined that those threads need to be restarted

    // Flag those functions to wrap it up
    pthread_mutex_lock(&wrapUpFlagMutex);
    wrapUpFlag = true;
    pthread_mutex_unlock(&wrapUpFlagMutex);

    // Join the threads, note that this will block
    pthread_join(thread3, NULL);
    pthread_join(thread2, NULL);
    pthread_join(thread1, NULL);

    // Flag those functions to...not...wrap it up
    pthread_mutex_lock(&wrapUpFlagMutex);
    wrapUpFlag = false;
    pthread_mutex_unlock(&wrapUpFlagMutex);

    // Launch those puppies again
    pthread_create(thread1, NULL, first_thread, NULL);
    ...
}

同样,这是一种模仿主义的方法。一个更健壮的方法可能涉及条件变量,重新设计调用结构,实际使用传递给线程函数的参数并返回pthread_exit()的值等等。

此外,根据您的约束,您可能会对pthread_kill等功能感兴趣。请注意,无论你走哪条道路,只要希望杀掉线程的行为能够为你清理一些事情,你就不会为自己省去任何麻烦。