linux中线程的4中锁机制

1.互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当 获取锁擦操作失败时,线程会进入睡眠,等待锁释放时被唤醒。

在这里插入代码片
pthread_mutex_t Device_mutex ;
int count=0;
void thread_func1()
{
	while(1)
	{
		pthread_mutex_lock(&Device_mutex);
		printf("thread1: %dn",count);
		pthread_mutex_unlock(&Device_mutex);
		count++;
		sleep(1);
	}
}

void thread_func2()
{
	while(1)
	{
		pthread_mutex_lock(&Device_mutex);
		printf("thread2: %dn",count);
		pthread_mutex_unlock(&Device_mutex);
		count++;
		sleep(1);
	}

}
int main()
{
	pthread_t thread1, thread2;
	pthread_mutex_init(&Device_mutex,NULL);
	if(pthread_create(&thread1,NULL,(void*)thread_func1,NULL) == -1)
	{
		printf("create IP81 Thread error !n");
		exit(1);
	}
	if(pthread_create(&thread2,NULL,(void *)thread_func2,NULL) == -1)
	{
		printf("create IP81_2 Thread error!n");
		exit(1);
	}
	sleep(1);
	pthread_join(thread1,NULL);
	pthread_join(thread2,NULL);
	pthread_mutex_destroy(&Device_mutex);
	return 0;
}

2.读写锁:rwlock,分为读锁和写锁,处于读操作时,可以允许多个线程同时获得读操作,但是同一时刻只有一个线程可以获得写锁。其他获取写锁失败的线程都会进入睡眠状态,直到写锁释放时被唤醒。注意:写锁会阻塞其他读写锁,读锁也不可以被其他线程获取。

在这里插入代码片
int counter;
pthread_rwlock_t rwlock;
 
void *th_write(void *arg);
void *th_read(void *arg);
 
 
int main(int argc, char *argv[])
{
 
	int i = 0;
	pthread_t tid[8];
	pthread_rwlock_init(&rwlock, NULL);
	//创建三个写线程
	for(i = 0; i<3; i++)
	{
		pthread_create(&tid[i], NULL, th_write, (void*)i);//不能&i 和 i = *((int*)arg)
	}
	//创建5个读线程
	for(i = 0; i<5; i++)
	{
		pthread_create(&tid[i+3], NULL, th_read, (void*)i);
	}
	for(i = 0; i < 8; i++)
	{
		pthread_join(tid[i], NULL);
	}
	pthread_rwlock_destroy(&rwlock);
}
 
void *th_write(void *arg)
{
	 int i = (int)arg;
	int t = 0;
	for( ; ; )
	{
		pthread_rwlock_wrlock(&rwlock);
		t = counter;
		usleep(1000);
		printf("write %d: %lu: counter = %d ++counter = %d\n", i, pthread_self(), t, ++counter);
		pthread_rwlock_unlock(&rwlock);
		usleep(10000);//这个延时大的目的是让读锁有机会进行读,不然一直让写锁独占
	}
	return NULL;
}
 
void *th_read(void *arg)
{
	 int i = (int)arg;
	for( ; ; )
	{
		pthread_rwlock_rdlock(&rwlock);
		printf("read %d: %lu: counter = %d\n", i ,pthread_self(), counter);
		pthread_rwlock_unlock(&rwlock);
		usleep(2000);
	}
	return NULL;
}

**3.自旋锁:**spinlock,在任何时刻同样只能有一个线程访问对象,但是当获取锁操作失败时,不会进入睡眠,而是会在原地自旋,直到锁释放。这样就节省了线程从睡眠状态被唤醒期间的消耗,在加锁时间短暂等环境下会极大提升效率。
**4.RCU:**read_copy_update,在修改数据时,首先需要读取数据,然后生成一个副本,对副本进行修改。修改完成后,再将老数据update成新数据。使用RCU时,读者几乎不需要同步开销,即不需要获得锁,也不使用原子指令,不会导致锁竞争,因此不用担心死锁问题。而对于读者的同步开销较大,它需要复制被修改 的数据,还必须使用锁机制同步并行其他写者修改操作。在有大量读操作,少量写操作的情况下效率比较高。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值