0
点赞
收藏
分享

微信扫一扫

线程之间通信

小沙坨 2022-04-06 阅读 142
linuxc语言

线程是共享相同地址空间的多个任务。所以线程之间通信可以利用 静态数据(全局变量)作为中介来实现。前面关于线程的创建中有给出例子。但是线程与主线程之间的执行顺序这个无法确定,主要看在时间片中能执行多少指令,也可以使用sleep()函数来延缓下面的指令的执行。

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>

char a[64]="I love you!";

void *fuc()
{
	sleep(1);
	stpcpy(a,"I hate you !");
	pthread_exit("come from pthread_exit");

}

int main()
{
	pthread_t a_thread;
	void *result;
	
	if((pthread_create(&a_thread,NULL,&fuc,NULL))!=0)
	{
		printf("pthread_creat is failed!\n");
		exit(-1);
	}
	printf("%s\n",a);  //此时a里面数据还未被线程修改,因为fuc里面有sleep
	
	sleep(3);

	printf("%s\n",a); //此时a里面的数据已经被修改,因为主线程sleep 3 a线程已经执行完
	
	stpcpy(a,"I love you,too!");
	printf("%s\n",a);
	
	pthread_join(a_thread,&result);
	printf("%s\n",(char*)result);
	
	return 0;
}

最后的结果如图:

 

 由于线程之间的执行顺序不确定性较大,为了消除不确定性导致的问题,引入了同步机制和互斥机制。

同步机制,是指多个任务按照约定的先后顺序相互配合完成一件事。为了执行同步机制还引入了信号量的P,V操作,P申请资源,V释放资源。

比如经典的生产者与消费者问题,读写问题,必须要在buf中写入数据之后才能进行读,在读的过程中不能进行写操作。

#include<stdio.h>
#include<semaphore.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>

char buf[32];
sem_t sem_r;  //可读缓冲区的个数
sem_t sem_w;  //可写缓冲区的个数

void *function(void *arg);

int main()
{
	pthread_t a_thread;
	
	if(sem_init(&sem_r,0,0)<0){    //初始化信号量,刚开始可读的资源为0
		perror("sem_init");     
		exit(-1);
	}
	
	if(sem_init(&sem_w,0,1)<0){    //初始化信号量,刚开始可写的资源为1
		perror("sem_init");     
		exit(-1);
	}
	
	if(pthread_create(&a_thread,NULL,&function,NULL)!=0) //需要先初始化信号量再创线程,因为                                                                                                                                                        
	{                                   //如果先创线程再初始化可能导致初始化两遍信号量
		printf("pthread_create is failed!\n");
		exit(-1);
	}
	
	printf("input 'quit' to exit\n");
	
	do{
		sem_wait(&sem_w);             //写之前先申请写资源 P(w)
		fgets(buf,32,stdin); 
		sem_post(&sem_r);              //写之后释放资源增加可读资源 v(r)
	}while(strncmp(buf,"quit",4)!=0);
	return 0;
}

void *function(void *arg)
{
	while(1)
	{
		sem_wait(&sem_r);          //读之前申请读的资源 p(r)
		printf("you enter %ld characters\n",strlen(buf));
		sem_post(&sem_w);           //读之后释放资源 增加可写的资源 v(w)
	}
}

互斥机制,使用mutex互斥锁,在访问临界资源时申请锁,访问完解锁。

当pv操作中的信号量只有01时也相当于互斥锁。

总结:

线程由于共享相同地址空间,所以通信很方便,但也容易由执行顺序导致通信出错。

引入pv操作和互斥锁来确保数据的正确性。

举报

相关推荐

0 条评论