linux系统编程:线程同步-互斥量(mutex)

                             线程同步-互斥量(mutex)

线程同步

多个线程同时访问共享数据时可能会冲突,于是需要实现线程同步。

一个线程冲突的示例

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define Loop 1000000
//全局资然
int counter = 0;
void *fun(void *argv)
{
	int i;
	for (i = 0; i < Loop; i++)
	{
		counter++;
	}
	return (void *)0;
}
int main(void)
{
	int i;
	pthread_t pid[2];
	for (i = 0; i < 10; i++)
	{
		counter = 0;
		pthread_create(&pid[0], NULL, fun, NULL);
		pthread_create(&pid[1], NULL, fun, NULL);
		pthread_join(pid[0], NULL);
		pthread_join(pid[1], NULL);
		printf("counter=%d\n", counter);
	}
	return 0;
}
//$ ./a.out
//counter = 2000000
//counter = 2000000
//counter = 2000000
//counter = 2000000
//counter = 2000000
//counter = 2000000
//counter = 2000000
//counter = 2000000
//counter = 1919439
//counter = 2000000
如果Loop越大,想必结果不一样的可能性越大。


互斥量

互斥量(mutex)就是解决线程冲突的一种常见方法。

#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
对以上代码加上互斥量

//mutex.c
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define Loop 1000000
//初始化
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
//全局资然
int counter = 0;
void *fun(void *argv)
{
	int i;
	for (i = 0; i < Loop; i++)
	{
		pthread_mutex_lock(&m);
		counter++;
		pthread_mutex_unlock(&m);
	}
	return (void *)0;
}
int main(void)
{
	int i;
	pthread_t pid[2];
	for (i = 0; i < 10; i++)
	{
		counter = 0;
		pthread_create(&pid[0], NULL, fun, NULL);
		pthread_create(&pid[1], NULL, fun, NULL);
		pthread_join(pid[0], NULL);
		pthread_join(pid[1], NULL);
		printf("counter=%d\n", counter);
	}
	pthread_mutex_destroy(&m);  //销毁互斥量
	return 0;
}

只需在需要同步的代码块加上“锁”即可。


关键区

被互斥量锁住的代码块,称作关键区(Critical Section):保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

关键区的范围,显然要尽可能的小。



CCPP Blog 目录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值