请教如何用pthread库实现线程的启动和暂停?

testpwd 2012-12-19 10:48:45
我在linux上,想用pthread库实现这样的功能:我有2个线程:一个主线程,一个工作线程,在主线程中创建工作线程。工作线程不总是工作,也就是说,创建的时候处于暂停状态或休眠状态(不占cpu),当主线程通知它工作的时候就开始工作。开始工作之后,当主线程需要暂停它的时候可以通知它使它暂停。然后工作线程又处于暂停状态(不占cpu)。之后类似,主线程可以随时通知工作线程开始工作,随时暂停工作线程。
我开始的想法是这样的:

pthread_t thread;
int enable = 0;

void* threadFunc(void* args) //工作线程函数
{
while(1)
{
if(enable)
{
work();
}
else
{
sleep(1);
}
}
return ((void*)0);
}

int main()
{
pthread_create(&thread, NULL, threadFunc, NULL);
enable = 1;
sleep(3);
enable = 0;
...
}


但感觉用sleep不太好,因为sleep的时间其实不好定。太长太短都不好。其实主线程什么时候启动什么时候暂停工作线程,都是确定的。主线程其实是响应用户的请求,用户说开始work就应该马上work,用户说停止就应该马上停止。
后来我想用条件变量,在工作线程中:

pthread_mutex_lock(&mutex));
pthread_cond_wait(&cond,&mutex);

在主线程中:

pthread_cond_signal(&cond);


但是这样只能启动,无法暂停?

不知道各位大侠有没有什么办法?代码应该如何写呢?
多谢了!

...全文
1251 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ninglei 2013-11-26
  • 打赏
  • 举报
回复
....有现成的挂起函数不用 用互斥量 楼上的都是大神
Simonyd 2013-06-30
  • 打赏
  • 举报
回复
学习了,(*^__^*) 嘻嘻……,谢谢。
  • 打赏
  • 举报
回复
http://blog.csdn.net/infoworld/article/details/8533892
testpwd 2012-12-21
  • 打赏
  • 举报
回复
非常感谢各位的指导!
prajna 2012-12-20
  • 打赏
  • 举报
回复
引用
能不能写个例子?
你自己的就可以啊,
void* threadFunc(void* args)  //工作线程函数
{
   while(1)
   {
      if(!pthread_pause)
      {
				printf("working...");
          //work();
      }
      else
      {  
				printf("rest...");
      }
			sleep(1);
   }
   return ((void*)0);
}
pthread_t thread;

int main()
{
     pthread_create(&thread, NULL, threadFunc, NULL);

		 while (1){
			 int c = getchar();
			 if (c=='s') pthread_suspend();
			 if (c=='r') pthread_resume();
			 //if (c=='c') pthread_pause_location();
		 }
		 return 0;
}
枫桦沐阳 2012-12-20
  • 打赏
  • 举报
回复
我来帮你拼接一下。 pthread_mutex_t mutex_pause = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond_pause = PTHREAD_COND_INITIALIZER; bool pthread_pause = false; void pthread_suspend(void) { if (pthread_pause == false) { pthread_mutex_lock( &mutex_pause ); pthread_pause = true; printf("------pthread pause------/n"); pthread_mutex_unlock( &mutex_pause ); } else { printf("pthread suspend already/n"); } } void pthread_resume(void) { if (pthread_pause == true) { pthread_mutex_lock(&mutex_pause); pthread_pause = false; pthread_cond_broadcast(&cond_pause); printf("------pthread resume------/n"); pthread_mutex_unlock(&mutex_pause); } else { printf("pthread resume already/n"); } } void* threadFunc(void* args) //工作线程函数 { while(1) { if(pthread_pause == false) { work(); } else { pthread_cond_wait(&cond); } } return ((void*)0); } int main() { pthread_create(&thread, NULL, threadFunc, NULL); pthread_resume(); pthread_cond_signal(&cond); sleep(3); pthread_suspend(); ... }
testpwd 2012-12-20
  • 打赏
  • 举报
回复
回楼上,这样唤醒之后如何暂停呢?
oyq_yangy 2012-12-20
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
在工作线程中合适的地方加锁读取一个初值为0的全局变量,如果该全局变量为1,表示主线程希望本子线程暂停; 主线程希望子线程暂停时,加锁设置这个全局变量为1?
最好不要这样用。子线程暂停(sleep?)后,怎样再去检查变量?除非不停的去读。这样的loop效果不好。 简单的pause, resume,用 pthread_mutex_lock(&mutex); pthread_cond_wait(&cond); pthread_mutex_unlock(&mutex); 就够,不需要变量,pthread_cond_wait会block等待唤醒。或者可以用信号量就行。。。
testpwd 2012-12-20
  • 打赏
  • 举报
回复
多谢gumh!不过你写的几个函数该如何用呢?能不能写个例子?
testpwd 2012-12-20
  • 打赏
  • 举报
回复
多谢zhao4zhong1 和 ynb119 。现在的思路是:
pthread_t thread; 
int enable = 0; 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;   
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    
void* threadFunc(void* args)  //工作线程函数 
{    
    while(1)    
    {       
        if(enable)       
        {     work();       
        }       
        else      
        {             
           pthread_mutex_lock(&mutex);
           pthread_cond_wait(&cond);
           pthread_mutex_unlock(&mutex);             
        }    
     }    
     return ((void*)0); 
}   

int main() 
{      
      pthread_create(&thread, NULL, threadFunc, NULL);      
      enable = 1;      
      pthread_cond_signal(&cond);
      sleep(3);
      enable = 0;      
      ... 
}
不知道这样有没有什么问题?
枫桦沐阳 2012-12-19
  • 打赏
  • 举报
回复
linux下好像没有如Windows下的线程suspend,resume机制。 只能通过你所说的pthread_mutex_lock,pthread_cond_wait等函数实现。 启动控制应该跟你最开始的思路一样,还得需要循环检测,就是把你的enable换成pthread_cond_wait,不需要sleep就是了。
prajna 2012-12-19
  • 打赏
  • 举报
回复
#include <stdio.h>   
#include <pthread.h>   
#include <stdlib.h>   
#include <unistd.h>   
  
pthread_mutex_t mutex_pause = PTHREAD_MUTEX_INITIALIZER;  
pthread_cond_t cond_pause = PTHREAD_COND_INITIALIZER;  
  
bool pthread_pause = false;  
  
void pthread_suspend(void)  
{  
    if (pthread_pause == false)  
    {  
        pthread_mutex_lock( &mutex_pause );  
        pthread_pause = true;  
        printf("------pthread pause------/n");  
        pthread_mutex_unlock( &mutex_pause );      
    }  
    else  
    {  
        printf("pthread suspend already/n");  
    }  
  
}  
  
  
void pthread_resume(void)  
{   
    if (pthread_pause == true)  
    {  
        pthread_mutex_lock(&mutex_pause);  
        pthread_pause = false;  
        pthread_cond_broadcast(&cond_pause);  
        printf("------pthread resume------/n");  
        pthread_mutex_unlock(&mutex_pause);   
    }  
    else  
    {  
        printf("pthread resume already/n");  
    }  
  
  
}  
  
  
void pthread_pause_location(void)  
{  
    pthread_mutex_lock(&mutex_pause);  
    while(pthread_pause)  
    {  
        pthread_cond_wait(&cond_pause, &mutex_pause);  
    }  
    pthread_mutex_unlock(&mutex_pause);   
}  
linxren 2012-12-19
  • 打赏
  • 举报
回复
pthread_mutex_lock(&mutex)); pthread_cond_wait(&cond,&mutex); 调用pthread_cond_wait这个之后不久暂停了么?
枫桦沐阳 2012-12-19
  • 打赏
  • 举报
回复
哦。原来是这种需求。 还是按你的思路,把两种方法结合一下。 子线程,判断还是使用enable,但是sleep用pthread_cond_wait来。 主线程,启动的时候先设定Enable=true然后pthread_cond_signal。 停止的时候直接设定Enable=false 但是enable原子操作(atomic_t)来实现安全些。
赵4老师 2012-12-19
  • 打赏
  • 举报
回复
在工作线程中合适的地方加锁读取一个初值为0的全局变量,如果该全局变量为1,表示主线程希望本子线程暂停; 主线程希望子线程暂停时,加锁设置这个全局变量为1?
testpwd 2012-12-19
  • 打赏
  • 举报
回复
多谢ynb119。但是把enable换成pthread_cond_wait似乎不行吧?工作线程一开始会处于wait,当主线程发出signal之后工作线程开始work,work完成之后循环,然后又wait了。这不是我想要的,我希望主线程发出signal之后工作线程开始work,然后一直work,当主线程发出暂停时工作线程就暂停。按照你的意思,主线程如何使工作线程暂停呢?

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧