线程互斥和同步-- 互斥锁

一. 线程分离
我们一般创建的线程是可结合的,这个时候如果我们调用pthread_jion()去等待的话,这种等待的方式是阻塞式等待,如果主线程一直等待,主线程就无法做其他的事情了,所以应该使用线程分离,让子线程由操作系统回收,主线程就不管了。
不管线程是否分离,它始终是在进程的内部执行的。
使用的函数接口是pthread_detach(pthread_t pid)
如果分离自己参数为pthread_self(),如果是主线程分离子线程,参数为pthread_id
二. 线程互斥
因为我们的多个线程是共享一个资源的,这个资源就是临界资源,多个线程对资源的访问就需要使用线程的同步和互斥
互斥,对资源的访问时串行的,原子的。即是, 每次只能有一个线程访问临界 资源
三.线程同步
如果我们的某一个线程的优先级特别高,那么它可能会一直占据这这临界资源,这个时候,其他的线程就无法使用这个临界资源,虽然我们实现了线程的互斥,但是只有一个线程 使用它,这也是不符合我们的实际需求的,所以这个时候需要使用线程的同步。
线程同步的意思就是说,每次使用完一个临界资源之后,都需要排队,打个形象的比喻就是,如果我们一个人进入一个单独自习室自习之后,出来的时候,必须排在其他的排在门口的人后面,不能直接出来又进去,这样的话,他就是一直占据着临界资源了。
四. 互斥锁
设置一个互斥锁,这个时候一次,创建一个全局的互斥锁。
在线程函数里面,每次一个线程 访问的临界资源的时候,首先要做的是就是获取这个锁,只有拿到锁之后才能对临界资源进行操作,然后每次在退出临界资源之前,要解锁,这样其他的线程进入的时候才不会永远拿不到锁。
整个函数结束前,要销毁锁。

对于互斥锁的一个深层次的理解
1. 互斥锁本身就是一个临界资源,所以对互斥锁的操作本身就是原子的。
2. 每次在线程 函数的内部,每次需要申请锁资源,如果申请失败,当前的线程就会被挂起,挂起就是该线程的PCB在等待队列里面。

死锁产生的情景
1. 多线程可能有多把锁,这个时候,如果其中的某些线程 都想要访问彼此的锁,这个时候可能 都拿不到,然后就产生了死锁。
2. 一个进程一把锁,可能由于代码错误,当它申请锁之后,已经 拿到了这把锁,然后他又去申请同样 的,这个时候就出现了死锁。

下面看代码的实现。
#include<stdio.h>
#include<pthread.h>
int count = 0; 

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;   //创建一把锁,使用宏进行初始化

void* pccount(void* arg)
{
	int i = 0;
	int temp = 0;
	while(i<50000000)
	{
		pthread_mutex_lock(&lock);   //加锁,如果锁资源是空,就拿到锁,如果锁资源不是空,就挂起等待
	//	temp=count;
		count=count+1;
		//printf("%d",temp);
		i++;
		pthread_mutex_unlock(&lock);   //操作完临界资源之后,要解锁,这样其他的线程才能够获取锁资源
	}
//	printf("%d\n",count);
	pthread_exit((void*)123);
}

int main()
{
	pthread_t pid1;
	pthread_t pid2;
	int i = pthread_create(&pid1,NULL,pccount,NULL);

	int m = pthread_create(&pid2,NULL,pccount,NULL);
	void* join1;
	void* join2;
	pthread_join(pid1,&join1);

	pthread_join(pid2,&join2);  //这里必须要有线程等待,不然没有打印结果
    pthread_mutex_destroy(&lock);   //销毁锁资源
	printf("%d\n",count);
	return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值