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

news/2024/5/19 3:26:30 标签: 线程, 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 目录


http://www.niftyadmin.cn/n/1802094.html

相关文章

linux系统编程:线程同步-读写锁(rwlock)

线程同步-读写锁(rwlock) 读写锁 读写锁是互斥量的细化&#xff1a;显然&#xff0c;只有对全局资然进行写入操作时&#xff0c;才需要同步&#xff1b;在对全局资然进行读取操作时&#xff0c;是不需要锁的。相关函数 pthread_rwlock_t //读写锁类型 pthread_rwlock_init /…

linux系统编程:线程同步-条件变量(cond)

线程同步-条件变量(cond) 生产者与消费者问题 再引入条件变量之前&#xff0c;我们先看下生产者和消费者问题&#xff1a;生产者不断地生产产品&#xff0c;同时消费者不断地在消费产品。 这个问题的同步在于两处&#xff1a;第一&#xff0c;消费者之间需要同步&#xff1a;同…

linux系统编程:线程同步-信号量(semaphore)

线程同步-信号量(semaphore) 生产者与消费者问题再思考 在实际生活中&#xff0c;只要有商品&#xff0c;消费者就可以消费&#xff0c;这没问题。但生产者的生产并不是无限的&#xff0c;例如&#xff0c;仓库是有限的&#xff0c;原材料是有限的&#xff0c;生产指标受消费指…

挑战面试编程:查找数组中第k大的数

查找数组中第k大的数 问题&#xff1a; 查找出一给定数组中第k大的数。例如[3,2,7,1,8,9,6,5,4]&#xff0c;第1大的数是9&#xff0c;第2大的数是8…… 思路&#xff1a; 1. 直接从大到小排序&#xff0c;排好序后&#xff0c;第k大的数就是arr[k-1]。 2. 只需找到第k大的…

CCPP Blog 目录

CCPP Blog 目录 专栏目录 数据结构与算法C指针C拾遗挑战面试编程 十六进制数转化为八进制数链表逆转的多种实现字符串匹配的双重递归式写法原码、反码、补码字符串替换字符串包含回文串、回文数字单词翻转、高斯公式、魔方矩阵、黑白球、3n1最大连续子序列和字符串转换为整数计…

C语言运行顺序和内存就地分配原则

不知道&#xff0c;为什么会出现这样的结果&#xff1f;答&#xff1a;此问题从二个方面解答&#xff1a;1> 编译器是上古三大神器的编译器之一&#xff0c;不带有任何只能辅助系统。2>本程序在语法没有任何问题&#xff0c;但是根据C语言编译语句自上而下 和 内存就地分…

编程中的问题

int arr[n]{1,2,3,4,5,6,7,8,9,11}?这个 N的值 是如何传来滴&#xff01;

vi 與 vim 的指令整理

&#xfeff;&#xfeff;vi 與 vim 的指令整理转自&#xff1a;http://www.vixual.net/blog/archives/tag/linuxvi 是 unix 家族下最功能強大的文字編輯器&#xff0c;讓用戶只要使用一個鍵盤就可以完成所有的編輯。而 vim 則是 vi 的加強版&#xff0c;甚至在 Windows 上也找…