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 目录

版权声明:本文为博主原创文章,转载,请注明出处。

时间: 2024-07-31 02:30:24

linux系统编程:线程同步-互斥量(mutex)的相关文章

(转)经典线程同步 互斥量Mutex

阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event> 前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用互斥量Mutex来解决这个问题. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源.使用互斥量Mutex主要将用到四个函数.下面是这些函数

转--- 秒杀多线程第七篇 经典线程同步 互斥量Mutex

阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event> 前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用互斥量Mutex来解决这个问题. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源.使用互斥量Mutex主要将用到四个函数.下面是这些函数

秒杀多线程第七篇 经典线程同步 互斥量Mutex

阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event> 前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用互斥量Mutex来解决这个问题. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源.使用互斥量Mutex主要将用到四个函数.下面是这些函数

linux系统编程--线程同步

同步概念 所谓同步,即同时起步,协调一致.不同的对象,对“同步”的理解方式略有不同. 如,设备同步,是指在两个设备之间规定一个共同的时间参考: 数据库同步,是指让两个或多个数据库内容保持一致,或者按需要部分保持一致: 文件同步,是指让两个或多个文件夹里的文件保持一致.等等 而,编程中.通信中所说的同步与生活中大家印象中的同步概念略有差异.“同”字应是指协同.协助.互相配合.主旨在协同步调,按预定的先后次序运行. 线程同步 同步即协同步调,按预定的先后次序运行. 线程同步,指一个线程发出某一功能调

Linux系统编程——线程同步与互斥:互斥锁

为什么需要互斥锁? 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源.这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印东西,如果不做任何处理的话,打印出来的东西肯定是错乱的. 下面我们用程序模拟一下这个过程,线程一需要打印" hello ",线程二需要打印" world ",不加任何处理的话,打印出来的内容会错乱: #include <stdio.h> #include <

线程同步---互斥量mutex

1. 问题引入:开两个线程同时对一个全局变量10万次做自加,结果会如何? #include <stdio.h> #include <string.h> #include <pthread.h> unsigned int g_cn = 0; void* thread_proc (void* arg) { unsigned int i; for (i = 0; i < 100000; i++) ++g_cn; return NULL; } int main (void

Linux系统编程——线程同步与互斥:无名信号量

信号量概述 信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问. 编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于 0 时,则可以访问,否则将阻塞.PV 原语是对信号量的操作,一次 P 操作使信号量减1,一次 V 操作使信号量加1. 信号量主要用于进程或线程间的同步和互斥这两种典型情况. 信号量用于互斥: 信号量用于同步: 在 POSIX 标准中,信号量分两种,一种是无名信号量,一种是有名信号量.无名信号量一般用

Linux系统编程——线程同步与互斥:读写锁

当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住.但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是由于互斥锁的排它性,所有其它线程都无法获取锁,也就无法读访问共享资源了,但是实际上多个线程同时读访问共享资源并不会导致问题. 在对数据的读写操作中,更多的是读操作,写操作较少,例如对数据库数据的读写应用.为了满足当前能够允许多个读出,但只允许一个写入的需求,线程提供了读写锁来实现.... www.worlduc.com/

秒杀多线程第七篇 经典线程同步 互斥量Mutex(续)

java使用Synchronized关键字实现互斥,而同时有Lock支持. 这两个的效果是等同的,Synchronized性能的起伏较大,而lock比较收敛. 为了代码的可读性,Synchronized更建议使用.