Linux上的线程控制,以及信号量

线程控制

  • 第一题

完成了如下功能:线程1把1,2,3,…,10打印在屏幕上(每隔4秒钟打印一个);另一个线程2把11,12,…,20打印在屏幕上(每隔2秒钟打印一个)

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
void *thread1_proc(void *arg)
{
	int i=0;
	while(i<10)
	{
		printf("thread1:%-5d",i);
		fflush(stdout);//printf是基于行缓冲的:只有在缓冲区满、刷新缓冲区或者遇到换行符的时候才把字符串显示在屏幕上,所以手动调用fflush刷新缓冲区
		sleep(4);
		i++;
	}
	printf("Thread1 finished!\n");
	pthread_exit(NULL);
}

void *thread2_proc(void *arg)
{
	int i=10;
	while(i<20)
	{
		printf("thread2:%-5d",i);
		fflush(stdout);
		sleep(2);
		i++;
	}
	printf("Thread2 finished!\n");
	pthread_exit(NULL);
}

void *m_thread_proc(void *arg){
	/** 
	* if flag==1
	* output 1-10 at intervals of four seconds
	* else output 11-20 at intervals of two seconds
	*/
	int flag=(int)arg;
	for(int i=flag==1?1:10;i<=10*flag;i++){
		printf("thread2:%-5d",i);
		fflush(stdout);
		sleep(2*flag);
	}
}

void *mm_thread_proc(void *arg){
	int *marg=(int*)arg;
	
	for(int i=marg[1];i<=marg[2];i++){
		printf("thread%d:%-5d",marg[0],i);
		fflush(stdout);
		sleep(marg[3]);
	}
}

int main()
{
	pthread_t thread1,thread2;
	int flag_1=1,flag_2=2;
	
	// 	thread name [0]
	// 	output [1]--[12]  
	//	delay [2] s
	int thread_1_arg[]={1,1,10,4};
	int thread_2_arg[]={2,11,20,2};
	
	/* 
	if(pthread_create(&thread1,NULL,thread1_proc,NULL)!=0)
		perror("Create thread1 failed");
	if(pthread_create(&thread2,NULL,thread2_proc,NULL)!=0)
		perror("Create thread2 failed");
	*/
		
	/* m_thread_proc
	if(pthread_create(&thread1,NULL,m_thread_proc,flag_1)!=0)
		perror("Create thread1 failed");
	if(pthread_create(&thread2,NULL,m_thread_proc,flag_2)!=0)
		perror("Create thread2 failed");
	*/
	
	if(pthread_create(&thread1,NULL,mm_thread_proc,thread_1_arg)!=0)
		perror("Create thread1 failed");
	if(pthread_create(&thread2,NULL,mm_thread_proc,thread_2_arg)!=0)
		perror("Create thread2 failed");
		
	pthread_join(thread1,NULL);
	pthread_join(thread2,NULL);
}

  1. 如果把参考代码中的两个pthread_join注释掉后会正常工作吗?为什么?

不会,如果没有pthread_join来阻塞等待子线程的话,主线程就提前结束了,没办法正常工作。

  1. 如果把thread2_proc函数中的pthread_exit换成exit,程序运行结果又有什么不同?

线程二在输出10个数之后,程序就结束了,exit函数是用来结束整个程序的,而pthread_exit是用来结束当前线程,而pthread_cancel可以用来结束其他子线程。

  1. 如果要求线程1、线程2共用同一个线程入口函数该如何修改代码?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W97d62L5-1616598008382)(https://i.loli.net/2021/03/24/FsHPtSCbDRq6JX9.jpg)]

  • 第二题

(反复的过程,不能只做一次)主线程负责从键盘获取(1)两个整数,子线程负责对这两个整数完成求和(2)运算并把结果打印出来,请编程实现该功能,并尝试是否可以要利用全局变量完成两个线程的同步。

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
sem_t can_add;//能够进行加法计算的信号量
sem_t can_scanf;//能够从键盘输入的信号量
int x,y;
void *thread_add(void *arg)//加法线程入口函数
{
	while(1)
	{
		sem_wait(&can_add);//申请信号量
		printf("x+y=%d\n",x+y);
		sem_post(&can_scanf);//释放信号量
	}
}
int main()
{
	pthread_t tid;
	sem_init(&can_add,0,0);//初始化can_add信号量
	sem_init(&can_scanf,0,1);	//初始化can_scanf信号量
	if(pthread_create(&tid,NULL,thread_add,NULL)<0)
	{
		printf("Create thread_add failed!\n");
		exit(0);
	}
	while(1)
	{
		sem_wait(&can_scanf);//申请信号量
		printf("Please input two integers:");
		scanf("%d%d",&x,&y);
		sem_post(&can_add);///释放信号量
	}		
}
  • 使用全局变量来进行锁
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
 
int x,y;
int can_add,can_scanf;
void *thread_add(void *arg)//加法线程入口函数
{
	while(1)
	{
		if(can_add==1){
			can_add=0; 
			printf("x+y=%d\n",x+y);
			can_scanf=1;
		}
	}
}
int main()
{
	pthread_t tid;
	can_add=0;
	can_scanf=1;
	
	if(pthread_create(&tid,NULL,thread_add,NULL)<0)
	{
		printf("Create thread_add failed!\n");
		exit(0);
	}
	while(1)
	{
		if(can_scanf==1){
			can_scanf=0;
			printf("Please input two integers:");
			scanf("%d%d",&x,&y);
			can_add=1;
		}
		
	}		
}

  • 第三题

    利用信号量实现:

    主线程负责从键盘获取两个整数,子线程1负责对这两个整数完成求和运算并把结果打印出来,子线程2负责对这两个整数完成乘法运算并打印出来。三个线程要求遵循如下同步顺序:

    (1) 主线程获取两个数;

    (2) 子线程1计算;

    (3) 子线程2计算;

    (4) 转(1)

    #include <stdio.h>
    #include <semaphore.h>
    #include <pthread.h>
    #include <stdlib.h>
    sem_t can_add,can_scanf,can_mul;
    int x,y;
    void *thread_add(void *arg)//加法线程入口函数
    {
    	while(1)
    	{
    		sem_wait(&can_add);//申请加法信号量
    		printf("x+y=%d\n",x+y);
    		sem_post(&can_mul);//释放乘法信号量
    	}
    }
    
    void *thread_mul(void *arg)//乘法法线程入口函数
    {
    	while(1)
    	{
    		sem_wait(&can_mul);//申请信号量
    		printf("x*y=%d\n",x*y);
    		sem_post(&can_scanf);//释放信号量
    	}
    }
    
    int main()
    {
    	pthread_t tid[2];
    	sem_init(&can_add,0,0);	//初始化can_add信号量
    	sem_init(&can_scanf,0,1);	//初始化can_scanf信号量
    	sem_init(&can_mul,0,0);	//初始化can_scanf信号量
    	
    	if(pthread_create(&tid[0],NULL,thread_add,NULL)<0)
    	{
    		printf("Create thread_add failed!\n");
    		exit(0);
    	}
    	
    	if(pthread_create(&tid[1],NULL,thread_mul,NULL)<0)
    	{
    		printf("Create thread_mul failed!\n");
    		exit(0);
    	}
    	
    	while(1)
    	{
    		sem_wait(&can_scanf);//申请信号量
    		printf("Please input two integers:");
    		scanf("%d%d",&x,&y);
    		sem_post(&can_add);///释放信号量
    	}		
    }
    
    
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值