我正在做一个关于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,它负责创建另外两个线程。一旦我停止所有线程,我需要重新启动它们。我尝试使用互斥锁和条件变量,但都失败了。
任何关于如何克服这一点的想法,可能只是一小段简单的代码会更有帮助
谢谢
答案 0 :(得分:4)
为什么需要启动和停止线程?保持线程运行通常更好,并且当它们没有任何有用的工作时阻止它们(例如条件变量)。
答案 1 :(得分:1)
我将做一些假设,因为正如比我更有知识的人所指出的,这种行为立即引发了为什么你(想你)需要摧毁/的问题重新创建这些线程,以及为什么这样做是模糊的:
send
和recv
函数可以访问某种标记机制这是一种鞋角方式,我几乎不敢接近它。如果不了解设计的约束,就很难表达出可以开始探索的一些选项。
首先,让我们设置send
和recv
函数,以便通知他们是时候再见:
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等功能感兴趣。请注意,无论你走哪条道路,只要希望杀掉线程的行为能够为你清理一些事情,你就不会为自己省去任何麻烦。