一、功能要求
使用三个线程,线程1用来监听用户输入和作为其他两个线程的监听器,线程2的主要内容为每隔一段时间,输出“hello 2”字符串,线程3的主要内容为每隔一段时间,输出“hello 3”字符串。根据输入的数据来改变线程1和线程2的状态
实现对线程的创建、暂停、恢复、终止等操作,通过输入数字来进行控制,具体来说,创建后默认是暂停的,
- 1恢复线程2,2暂停线程2,3终止线程2,
- 5恢复线程3,6暂停线程3,7终止线程3。
其中,恢复与暂停可以反复交替进行。
二、主要函数
pthread_create
:
UNIX环境创建线程函数
pthread_join:
用来等待一个线程的结束。
前两个、后两个成对使用,根据场景需要可交叉使用
pthread_mutex_lock:
互斥锁加锁
pthread_mutex_unlock:
互斥锁解锁
pthread_cond_signal:
条件唤醒
pthread_cond_wait:
条件等待
三、运行截图
为什么不能立即暂停/挂起线程,输入2或者6的时候线程2、3都会有一个输出?
答: 在线程1中读取的输入,在线程2、3中执行的暂停/挂起操作,并不能立即做出反应
四、主要代码
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
/*
1恢复线程2,2暂停线程2,3终止线程2,
5恢复线程3,6暂停线程3,7终止线程3。
*/
static int input=0; //接收键盘输入
static pthread_t id1,id2,id3;//线程1、2、3
//条件变量与互斥锁初始化
pthread_cond_t c2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t c3 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t m3 = PTHREAD_MUTEX_INITIALIZER;
//线程1
void FunOne(void) {
//首次启动堵塞线程2、3
pthread_mutex_lock(&m2);
pthread_mutex_lock(&m3);
while(1) {
scanf("%d", &input);
switch(input) {
case 1:
//恢复线程2;
printf("恢复线程2...\n");
pthread_cond_signal(&c2);//发送信号唤醒阻塞等待的进程
pthread_mutex_unlock(&m2);//在while循环内会被多次调用
break;
case 3:
//终止线程2;
pthread_cancel(id2);
printf("终止线程2...\n");
break;
case 5:
//恢复线程3;
printf("恢复线程3...\n");
pthread_cond_signal(&c3);
pthread_mutex_unlock(&m3);
break;
case 7:
//终止线程3;
pthread_cancel(id3);
printf("终止线程3...\n");
break;
}
}
}
//线程2
void FunTwo(void) {
pthread_mutex_lock(&m2);
while(1) {
if(input==2) {
printf("挂起线程2...\n");
pthread_cond_wait(&c2, &m2);//执行这个函数的线程将会被挂起
} else {
sleep(2);
printf("hello 2! \n");
}
}
pthread_mutex_unlock(&m2);
}
//线程3
void FunThree(void) {
pthread_mutex_lock(&m3);
while(1) {
if(input==6) {
printf("挂起线程3...\n");
pthread_cond_wait(&c3, &m3);//执行这个函数的线程将会被挂起
} else {
sleep(2);
printf("hello 3! \n");
}
}
pthread_mutex_unlock(&m3);
}
int main(int argc,char* argv[]) {
int res1 = pthread_create (&id1, NULL, (void *) FunOne, NULL);
sleep(1);//先让线程1抢占cpu,通过互斥锁让线程2、3阻塞
int res2 = pthread_create (&id2, NULL, (void *) FunTwo, NULL);
int res3 = pthread_create (&id3, NULL, (void *) FunThree, NULL);
if(res1!=0||res2!=0||res3!=0) {
printf("create error!\n");
return -1;
}
/**
*将进程阻塞,来执行指定线程
*/
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_join(id3,NULL);
pthread_mutex_destroy(&m2);//销毁互斥锁
pthread_mutex_destroy(&m3);//销毁互斥锁
return 0;
}
五、总结
线程2、3的第一次暂停是因为线程1先对互斥锁上锁了,而后面线程2、3的暂停是因为它们自己在等待条件信号
这里不能只用一个互斥锁和一个条件变量来实现,当其中一个线程互斥锁解锁或者发送一个条件信号的时候,会唤醒其他正在等待的线程,并不能控制确定的一个线程的执行。可以通过设置一些全局变量来尝试控制。
代码可能存在其他问题,仅供参考!