POSIX 互斥锁

2024-06-12 23:48
文章标签 互斥 posix

本文主要是介绍POSIX 互斥锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载地址:http://blog.csdn.net/wypblog/article/details/7264315


Linux下为了多线程同步,通常用到锁的概念。

POSIX下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。
它主要用如下5个函数进行操作。
1:pthread_mutex_init( pthread_mutex_t  * mutex,const pthread_mutexattr_t *attr);
初始化锁变量mutex。attr为锁属性,NULL值为默认属性。
2:pthread_mutex_lock( pthread_mutex_t  *mutex);加锁
3:pthread_mutex_tylock( pthread_mutex_t  *mutex);加锁,但是与2不一样的是当锁已经在使用的时候,返回为EBUSY,而不是挂起等待。
4:pthread_mutex_unlock( pthread_mutex_t  *mutex);释放锁
5:pthread_mutex_destroy( pthread_mutex_t *mutex );使用完后释放


下面这个例子首先是创建了两个线程,线程1从0加到49,线程2从50加到99,如果加了锁,打印的结果就是按照先后顺序正确打印,结果如下:

add1: sum is 1225
add2: sum is 4950

如果我们把线程里面加锁的部分去掉的话,两个线程就会交叉运行,最后的结果就不一定了。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>typedef struct ct_sum
{int sum;pthread_mutex_t lock;
}ct_sum;void* add1(void* cnt)
{int i;pthread_mutex_lock(&(((ct_sum*)cnt)->lock));for(i = 0; i < 50; i++){((ct_sum*)cnt)->sum += i;usleep(1000);}printf("%s: sum is %d\n", __func__, ((ct_sum*)cnt)->sum);pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));pthread_exit(NULL);
}void* add2(void* cnt)
{int i;pthread_mutex_lock(&(((ct_sum*)cnt)->lock));for(i = 50; i < 100; i++){((ct_sum*)cnt)->sum += i;usleep(1000);}printf("%s: sum is %d\n", __func__, ((ct_sum*)cnt)->sum);pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));pthread_exit(NULL);
}int main(void)
{int i;pthread_t ptid_1, ptid_2;int sum = 0;ct_sum cnt;pthread_mutex_init(&(cnt.lock), NULL);cnt.sum = 0;pthread_create(&ptid_1, NULL, add1, &cnt);pthread_create(&ptid_2, NULL, add2, &cnt);pthread_join(ptid_1, NULL);pthread_join(ptid_2, NULL);pthread_mutex_destroy(&(cnt.lock));return 0;
}
注:线程里面每个循环加一个延时,就是为了能够比较明显的看到加锁与不加锁的区别。


这篇关于POSIX 互斥锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1055685

相关文章

java线程深度解析(二)——线程互斥技术与线程间通信

http://blog.csdn.net/daybreak1209/article/details/51307679      在java多线程——线程同步问题中,对于多线程下程序启动时出现的线程安全问题的背景和初步解决方案已经有了详细的介绍。本文将再度深入解析对线程代码块和方法的同步控制和多线程间通信的实例。 一、再现多线程下安全问题 先看开启两条线程,分别按序打印字符串的

Linux多线程——POSIX信号量与环形队列版本之生产消费模型

文章目录 POSIX信号量POSIX的操作初始化销毁等待信号量(申请资源)发布信号量(放下资源) 环形队列之生产消费模型 POSIX信号量 POSIX信号量和System V信号量是不同的标准 但是实现的功能是一样的,都是为了解决同步的问题 我们说信号量指的就是资源的数量 在生产者与消费者模型里面,生产者与消费者所认为的资源是不同的 生产者认为空间是资源,因为每次都要

Java并发:互斥锁,读写锁,Condition,StampedLock

3,Lock与Condition 3.1,互斥锁 3.1.1,可重入锁 锁的可重入性(Reentrant Locking)是指在同一个线程中,已经获取锁的线程可以再次获取该锁而不会导致死锁。这种特性允许线程在持有锁的情况下,可以递归地调用自身的同步方法或代码块,而不会因为再次尝试获取相同的锁而被阻塞。显然,通常的锁都要设计成可重入的。否则就会发生死锁。 synchronized关键字,就是

深入理解C语言中的POSIX定时器

引言 在Unix和类Unix系统中,定时器是一种常见的机制,用于在特定时间间隔后执行某些操作。POSIX定时器因其灵活性和功能丰富而被广泛采用。本文将深入探讨POSIX定时器的工作原理、内部机制、使用方法及其在实际开发中的应用。 POSIX定时器基础 POSIX定时器是一种高级定时器接口,它允许用户创建定时器并指定定时器到期时的动作。POSIX定时器支持以下特性: 信号通知:定时器到

三个同步与互斥问题之生产者与消费者

#include<stdio.h> #include<pthread.h> pthread_mutex_t  mutex; #define Max 10 pthread_cond_t pro; pthread_cond_t con; int buffer=0;//全局变量----一开始为0,只有生产者可以执行 void deal_produce(

三个同步与互斥问题之哲学家就餐

#include<stdio.h> #include <semaphore.h> #include<pthread.h> //筷子作为mutex   pthread_mutex_t chopstick[5] ;   int eatnum[5]={5,5,5,5,5}; void *eat_think(void *arg)   {       int i= *(cha

FreeRTOS学习笔记—④RTOS通信管理篇/同步互斥与通信(正在更新中)

二、RTOS的核心功能   RTOS的核心功能块主要分为任务管理、内核管理、时间管理以及通信管理4部分,框架图如下所示:   (1)任务管理:负责管理和调度任务的执行,确保系统中的任务能够按照预期运行。   (2)内核管理:负责系统核心功能的管理,包括内存、中断、异常处理和系统启动等。   (3)时间管理:负责所有与时间相关的操作,包括系统时钟、定时器、任务延迟和周期性任务的执行。   (4)通

【Linux】多线程:POSIX库、线程管理、线程ID

目录 一、POSIX线程库 二、线程ID 三、动态库加载 四、再谈线程ID 一、POSIX线程库 原生库:指的是操作系统自带的库,如POSIX线程库,在类Unix系统中通常是原生支持的。这些库是操作系统的一部分,提供了系统级的线程管理功能。 【了解】兼容性和标准化 POSIX 标准:POSIX(Portable Operating System Interface)

Java-互斥锁死锁释放锁

互斥锁         互斥锁(Mutex Lock)是一种同步机制,用于确保在任何时刻只有一个线程可以访问特定的代码段(临界区),从而防止数据竞争和不一致性。 使用方法: 在Java中,可以使用synchronized关键字或ReentrantLock类来实现互斥锁。使用lock()方法获取锁,使用unlock()方法释放锁。 特点: 确保线程安全,防止多个线程同时访问共享资源。简单易

条件变量:为什么要与互斥锁配套使用?为什么要使用while来避免虚假唤醒?

首先关于条件变量的引入: 假想在这样的情况下,多个线程需要等待某个条件才能继续工作(如生产者消费者模型中,消费者需要等待流水线上有产品后才能消费),如果只使用互拆锁,则多个线程要不停的查询流水线是否为空这个状态,并且查询这个操作需要加入临界区,因为流水线不仅同时有多个消费者,还有生产者在生产,不加锁的话可能出现两个甚至多个消费者对同一个产品动手的情况。这种不停查询的操作是很蠢的,因此引入了条件变