Pthread线程 —— 多线程同步 互斥锁(mutex)

Linux线程同步之互斥量加锁解锁pthread_mutex_init、pthread_mutex_destroy、pthread_mutex_lock、 pthread_mutex_unlock 阅读详情

多线程的同步机制

  对于多线程程序来说,同步(synchronization)是指在一定的时间内只允许某一个线程访问某个资源 。而在此时间内,不允许其它的线程访问该资源。Linux下提供了多种方式来处理线程同步,最常用的是互斥锁(mutex)、条件变量(condition variable)和信号量(sem)。

互斥锁(mutex)

  互斥锁是一个特殊的变量,它有锁上(lock)和打开(unlock)两个状态。互斥锁一般被设置成全局变量。打开的互斥锁可以由某个线程获得。一旦获得,这个互斥锁会锁上,此后只有该线程有权打开。其它想要获得互斥锁的线程,会等待直到互斥锁再次打开的时候。我们可以将互斥锁想像成为一个只能容纳一个人的洗手间,当某个人进入洗手间的时候,可以从里面将洗手间锁上。其它人只能在互斥锁外面等待那个人出来,才能进去。在外面等候的人并没有排队,谁先看到洗手间空了,就可以首先冲进去。
  互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock这几个函数以完成锁的初始化,锁的销毁,上锁和释放锁操作。
  pthread_mutex_t 的定义:

typedef union
{
    struct __pthread_mutex_s
    {
        int __lock;
        unsigned int __count;
        int __owner;
#if __WORDSIZE == 64
        unsigned int __nusers;
#endif
        /* KIND must stay at this position in the structure to maintain
             binary compatibility.  */
        int __kind;
#if __WORDSIZE == 64
        int __spins;
        __pthread_list_t __list;
#define __PTHREAD_MUTEX_HAVE_PREV      1
#else
        unsigned int __nusers;
        __extension__ union
        {
            int __spins;
            __pthread_slist_t __list;
        };
#endif
    } __data;
    char __size[__SIZEOF_PTHREAD_MUTEX_T];
    long int __align;
} pthread_mutex_t;
锁的创建

  锁可以被动态或静态创建,可以用宏PTHREAD_MUTEX_INITIALIZER来静态的初始化锁,采用这种方式比较容易理解,互斥锁是pthread_mutex_t的结构体,而这个宏是一个结构常量,如下可以完成静态的初始化锁:

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
另外锁可以用pthread_mutex_init函数动态的创建,函数原型如下:
    int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr)
锁的属性

  互斥锁属性可以由 pthread_mutexattr_init(pthread_mutexattr_t *mattr); 来初始化,然后可以调用其他的属性设置方法来设置其属性;
  互斥锁的类型:有以下几个取值空间:

  PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。

  PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

  PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。

  PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

可以用

pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)

获取或设置锁的类型。

锁的释放

  调用pthread_mutex_destory之后,可以释放锁占用的资源,但这有一个前提上锁当前是没有被锁的状态。

锁的操作

  对锁的操作主要包括加锁 pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个。

    int pthread_mutex_lock(pthread_mutex_t *mutex)

  int pthread_mutex_unlock(pthread_mutex_t *mutex)

  int pthread_mutex_trylock(pthread_mutex_t *mutex)

  pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待

锁的使用
#include <pthread.h>  
#include <stdio.h>  

pthread_mutex_t mutex ;

void *print_msg(void *arg)
{  
    int i=0;  
    pthread_mutex_lock(&mutex);  
    for(i=0;i<15;i++)
    {  
        printf("output : %d\n",i);  
        usleep(100);  
    }  
    pthread_mutex_unlock(&mutex);  
}  
int main(int argc,char** argv)
{  
    pthread_t id1;  
    pthread_t id2;  
    pthread_mutex_init(&mutex,NULL);  
    pthread_create(&id1,NULL,print_msg,NULL);  
    pthread_create(&id2,NULL,print_msg,NULL);  
    pthread_join(id1,NULL);  
    pthread_join(id2,NULL);  
    pthread_mutex_destroy(&mutex);  
    return 1;  
}  
总结

  关于互斥锁,可能有些地方,不太容易懂。比如,互斥锁锁什么?简单的来说,互斥锁用的限制在同一时刻,其他的线程执行pthread_mutex_lock和pthread_mutex_unlock之间的指令。
  

【操作系统】互斥锁 mutex 结构解析 在上面的代码中,首先使用 pthread_mutex_lock 函数获取锁,然后获取 __owner 字段的值,最后使用 pthread_mutex_unlock 函数释放锁。如果 __owner 字段的值不为 0,则表示该锁当前被某个线程持有,您可以通过该值来确定是哪一个线程持有了该锁。:锁的类型,包括 PTHREAD_MUTEX_NORMAL(普通锁)、PTHREAD_MUTEX_RECURSIVE(递归锁)和 PTHREAD_MUTEX_ERRORCHECK(检错锁)。:锁的计数器,用于支持递归锁。 阅读详情

相关推荐

多线程函数详解 Multithreading

文章目录一、pthread_create线程函数二、pthread_join()函数三、互斥锁 pthread_mutex_init()函数 一、pthread_create线程函数 pthread_create是UNIX环境创建线程函数 头文件 #include<pthread.h> 函数声明 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), vo

weixin_49546568的博客 587

pthread_mutex_lock函数

pthread_mutex_lock函数是一个线程同步函数,用于对互斥锁进行加锁操作。它阻塞调用线程,直到可以获得互斥锁为止。如果互斥锁已经被其他线程锁定,则调用线程将被阻塞,直到互斥锁被解锁。指向的互斥锁已经被其他线程锁定,则调用线程将被阻塞,直到互斥锁被解锁。指向的互斥锁当前没有被锁定,则调用线程将获得锁,并继续执行。该函数返回值为0表示成功加锁,非零值表示失败。函数来释放锁,以避免死锁的情况发生。是一个指向互斥锁变量的指针。

weixin_45066931的博客 6906

pthread_mutex_lock函数深度解析

本文深入解析了POSIX线程库中的pthread_mutex_lock函数,从历史背景、设计理念到实际应用。文章详细介绍了互斥锁的核心概念、不同类型及适用场景,通过生产者-消费者模型等典型示例展示了其实现机制。重点分析了函数的多层次实现策略(快速路径、中速路径、慢速路径)和设计权衡,提供了完整代码示例和流程图说明。最后总结了互斥锁使用的最佳实践和常见陷阱,为开发者提供了全面的技术参考。

weixin_42108533的博客 1500

pthread_mutex_lock

pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);      描述 pthread_mutex_lock()函数锁住由mutex指定的mute

linking530的专栏 2143

cst使用局部网格加密,手动加密,special设置等方法合理网格布局加速仿真速度

在CST中,计算复杂模型或者阵列的时候往往需要耗费大量仿真时间,除了使用更高性能的电脑或工作站进行仿真,合理对CST的仿真网格进行适当设置也是必不可少的一步。CST中网格设置影响模拟的精度和速度,因此花时间理解网格过程是很重要的。

OVEN_b612的博客 1万+

使用GDScript(godot)生成仿杀戮尖塔地图

使用GDScript(godot)生成仿杀戮尖塔地图 extends Node2D export (PackedScene) var Ball var 被连接数 = {} # 每个怪物被下层怪物连接的数量 最多为2 var 连接1 = {} # 第一次连接的上层怪物位置 var 连接2 = {} # 第二次连接的上层怪物位置 var 怪物数量 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0] # 每层怪物的数量 var 总层数 =8 # 总层数 var 怪物坐标行 = {} #

weixin_45038716的博客 3010

互斥锁pthread_mutex_init()函数

互斥锁pthread_mutex_init()函数 linux下为了多线程同步,通常用到锁的概念。 posix下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。 即对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。 使用互斥锁(互斥)可以使线程按顺序执行。通常,互

择一事终一生 1298

Aider的Repo Map功能

要把整个项目的所有文件添加到 Repo Map 中,需要调整 Aider 的行为,让它扫描整个代码库并将所有文件纳入 Repo Map。在使用 Aider 时,Repo Map 默认只包含当前会话中明确指定的文件(通过命令行传入的。通过命令行将整个项目的文件列表传递给 Aider,使其初始化时包含所有文件。,让 Aider 在初始化时自动加载整个项目的文件到。如果你的项目是 Git 仓库,Aider 可以通过。在 Aider 的交互模式中,手动添加整个项目文件。,从而生成包含所有文件的 Repo Map。

qq_41638872的博客 1637

Linux多线程开发-线程同步-互斥锁pthread_mutex_t

1、互斥锁 同一时刻只允许一个线程对临界区进行访问。POSIX库中用类型pthread_mutex_t来定义互斥锁,类型在pthreadtypes.h中定义。 2、如何声明一个互斥锁 #include <pthread.h> pthread_mutex_t mutex; 3、如何初始化一个互斥锁 //静态初始化互斥锁 pthread_mutex_t mutex = PT...

健忘16的博客 552

骚操作,尝试使用Xilinx XVC协议,通过Jlink来下载调试Xilink zynq FPGA芯片

最近一直在玩zynq芯片,手头使用的Xilinx Platform USB Cable 下载线真是辣鸡,速度慢如蜗牛,每次下载bit文件或者烧写flash文件都要大半天,实在是难以忍受。逻辑分析仪看了下xilinx的下载线,速度只有6.25M,并且数据间隔非常大,不懂这线的开发者咋想的,这总线利用率真是低到爆了 上图为xilinx DLC 10下载线波形,惨不忍睹! 为了不浪费生命在下载等待时间上,我打算找找看有没有别的仿真调试选择。经过一番查找后发现Xilinx的仿真器好像选择不是很多,要么贵死要

听我瞎扯淡的博客 1万+

GN算法边介数计算优化指南:如何提升大规模社交网络分析效率

本文深入探讨了GN算法在大规模社交网络分析中的核心瓶颈——边介数计算,并提供了从算法优化到工程部署的完整性能提升方案。通过引入Brandes算法、并行计算、增量更新及分布式处理等策略,有效解决了传统GN算法在处理百万级网络时效率低下的问题,为社交网络社区划分等实际应用提供了高效解决方案。

weixin_29196613的博客 485

C多线程编程---互斥锁mutex

文章目录1、多线程的问题引入2、互斥锁1、初始化一个互斥锁:2、加锁:3、解锁:4、注销互斥锁:5、pthread_mutex_lock()和pthread_mutex_trylock()区别6、解锁要满足的条件: 1、多线程的问题引入 多线程的最大的特点是资源的共享,但是,当多个线程同时去操作(同时去改变)一个临界资源时,会破坏临界资源。如利用多线程同时写一个文件: #include <s...

qq_23929673的博客 998

单细胞转录组肿瘤细胞识别:inferCNV与CopyKAT实战解析

单细胞转录组测序(scRNA-seq)是解析肿瘤微环境的重要技术,但如何从海量细胞中准确区分恶性细胞与正常细胞,始终是数据分析的关键难题。传统marker注释在异质性肿瘤中常失效,而基于拷贝数变异(CNV)的推断方法为这一问题提供了更稳健的解决路径。CNV通过检测染色体大片段的增益或缺失,可在无先验标记的情况下识别恶性细胞,尤其适合实体瘤研究。inferCNV利用染色体滑动窗口分析相对表达量,生成直观的CNV热图;CopyKAT则结合高斯混合模型对每个细胞直接分类,输出肿瘤/正常/非整倍体标签。本文从原理出

weixin_31236101的博客 247

C++多线程之——pthread_mutex_t

由于我们在访问共享资源之前使用了 pthread_mutex_lock 来锁定互斥锁,在访问完成后使用 pthread_mutex_unlock 来解锁,因此可以确保只有一个线程能够修改计数器的值,从而避免了竞争条件。在这个示例中,我们将创建两个线程,它们将同时递增一个共享计数器,但由于使用了互斥锁,我们可以确保同时只有一个线程能够修改计数器的值。它尝试获取互斥锁,如果互斥锁已经被另一个线程锁定,它会立即返回一个错误代码,而不会阻塞。如果互斥锁已经被另一个线程锁定,调用线程将会阻塞,直到互斥锁变为可用。

ALL BE WELL的博客 2429

【WRFDA教程】客观分析(OBSGRID)详解

客观分析(OBSGRID)详解

WW、forever的博客 1133

【YOLOv8全方位学习手册】第四章 数据增强:从扩充数据到塑造模型的认知边界

"""使用 Albumentations 做自定义增强,兼容 YOLO 格式"""])# 转成 numpy# boxes 必须是 [[x_min,y_min,x_max,y_max], ...]# 在数据加载时调用你可以把集成到 PyTorch 的 Dataset 类里,或使用 Ultralytics 自带的DataLoader。

VectorShift的博客 211

线程同步与互斥锁

相比多进程模型,多线程模型最大的优势在于数据共享非常方便,同一进程内的多个线程可以使用相同的地址值访问同一块内存数据。但是,当多个线程对同一块内存数据执行“读−处理−更新”操作时,会由于线程的交叉执行而造成数据的错误。 例如以下代码段,当 thread_func() 同时在多个线程中执行时,更新到 glob_value 中的值就会互相干扰,产生错误结果。 #define LOOP_COUNT ...

Coulson的博客 688

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Linux多线程 -互斥锁 pthread_mutex

/* review sem for pthread && pthread_mutex * c++ virtual function use * pthread_mutex 使用场景:多线程操作global变量&&share function时(互斥) * */ #include <stdio.h> #include <stdlib.h&g...

5266的博客 792

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Linux下C语言多线程(第二篇)线程互斥pthread_mutex_t()

面先来一个实例来感受下Linux下C语言多线程编程的乐趣!我们通过创建两个线程来实现对一个数的递加。先不去理会代码的含义,我们先运行linux,在其中编写我们的第一个C语言多线程程序。 [cpp] view plain copy #include    #include    #include    #include    #define MAX

JiangzhouHe的博客 4294

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Linux多线程(六)互斥锁

     线程实际运行过程中,我们经常需要多个线程保持同步。这时可以用互斥锁来完成任务;互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock四个函数。int pthread_mutex_init(pthread_mutex_t *restrict mutex,   ...

qq_38211852的博客 265

操作系统~Linux~线程的互斥,mutex互斥锁的使用及其原理

1.临界资源:凡是被线程共享访问的资源都是临界资源(多线程、多进程打印数据到显示器,显示器就是临界资源)2.临界区:代码中访问临界资源的代码(在代码中,不是所有的代码都是进行访问临界资源的。而访问临界资源的代码区域我们称之为临界区)3.对临界区进行保护的功能,本质就是对临界资源的保护。方式:互斥或者同步4.互斥:在任意时刻,只允许一个执行流访问某段代码(访问某部分资源〉,就可以称之为互斥5.同步:一般而言,让访问临界资源的过程在安全的前提下(一般都是互斥and原子的),让访问资源具有一定的顺序性(具有合理性

Zebra的博客 2811

C多线程编程之mutex

在C语言的多线程编程中,POSIX线程(pthread)库是一个强大的工具,提供了丰富的功能用于线程管理和同步。pthread库的头文件是pthread.h,它包含了创建和管理线程以及线程间同步的所有函数和数据类型定义。通过包含pthread.h头文件,可以使用POSIX线程库提供的各种功能来实现多线程程序。互斥锁是一个重要的同步工具,用于确保多线程环境下对共享资源的安全访问。理解和正确使用这些功能是编写高效、安全的多线程程序的关键。

limc00的博客 1048

线程同步(锁/信号量)

声明: 本篇博客的学习途径主要为以下网站和课堂讲解,发博客目的仅为学习使用,在该博客的基础上做了一定程序的简略和修改。 参考博客 : 原文链接: https://blog.youkuaiyun.com/isunbin/article/details/83415873 https://www.zhihu.com/question/66733477?sort=created 文章目录线程同步互斥锁pthread_mutex_init() 互斥锁初始化pthread_mutex_lock() 互斥锁直接上锁pthread_m

AKUANer的博客 277

Linux线程-互斥锁

在线程实际运行过程中,防止共享资源被并发访问。这时可以用互斥锁来完成任务;互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock这几个函数以完成锁的初始化,锁的销毁,上锁和释放锁操作 一、什么是互斥锁 互斥锁是另一种用于多线程中的同步访问方法,它允许程序锁住某个对象,使得每次只能有一个线程访问它。为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后

qinjie的博客 591

【多线程】互斥锁 {竞态条件与同步机制;多线程的数据竞争问题,互斥锁的基本用法,pthread_mutex系列函数,互斥锁的原理;可重入函数和线程安全;死锁;其他常见的各种锁}

【多线程】互斥锁 {竞态条件与同步机制;多线程的数据竞争问题,互斥锁的基本用法,pthread_mutex系列函数,互斥锁的原理;可重入函数和线程安全;死锁;其他常见的各种锁}

52Herzt的博客 828

Pthread_mutex_t锁

[cpp] view plain copy linux下为了多线程同步,通常用到锁的概念。   posix下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。   它主要用如下5个函数进行操作。   1:pthread

Ycx_lq的博客 401
上一篇: Linux 下各种打包压缩解压命令
下一篇: Pthread 线程 —— 多线程同步 条件变量(cond)
zorro721
博客等级 码龄16年 15粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值