【Linux系统编程】互斥锁
00. 目录
文章目录
- 00. 目录
- 01. 互斥锁引入
- 02. 互斥锁的操作流程
- 03. 互斥锁相关函数
- 3.1 互斥锁初始化
- 3.2 互斥锁加锁
- 3.3 互斥锁解锁
- 3.4 互斥锁销毁
- 04. 互斥锁示例
- 05. 总结
01. 互斥锁引入
为什么需要互斥锁?
在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印东西,如果不做任何处理的话,打印出来的东西肯定是错乱的。
下面我们用程序模拟一下这个过程,线程一需要打印“ hello ”,线程二需要打印“ world ”,不加任何处理的话,打印出来的内容会错乱:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>// 打印机
void printer(char *str)
{while(*str!='\0'){putchar(*str); fflush(stdout);str++;sleep(1);}printf("\n");
}// 线程一
void *thread_fun_1(void *arg)
{char *str = "hello";printer(str); //打印
}// 线程二
void *thread_fun_2(void *arg)
{char *str = "world";printer(str); //打印
}int main(void)
{pthread_t tid1, tid2;// 创建 2 个线程pthread_create(&tid1, NULL, thread_fun_1, NULL);pthread_create(&tid2, NULL, thread_fun_2, NULL);// 等待线程结束,回收其资源pthread_join(tid1, NULL);pthread_join(tid2, NULL); return 0;
}
测试结果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out
hwoelrlldodeng@itcast:/mnt/hgfs/LinuxHome/code.bak2$
实际上,打印机是有做处理的,我在打印着的时候别人是不允许打印的,只有等我打印结束后别人才允许打印。这个过程有点类似于,把打印机放在一个房间里,给这个房间安把锁,这个锁默认是打开的。当 A 需要打印时,他先过来检查这把锁有没有锁着,没有的话就进去,同时上锁在房间里打印。而在这时,刚好 B 也需要打印,B 同样先检查锁,发现锁是锁住的,他就在门外等着。而当 A 打印结束后,他会开锁出来,这时候 B 才进去上锁打印。
而在线程里也有这么一把锁——互斥锁(mutex),互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即加锁( lock )和解锁( unlock )。
02. 互斥锁的操作流程
1)在访问共享资源后临界区域前,对互斥锁进行加锁。
2)在访问完成后释放互斥锁上的锁。
3)对互斥锁进行加锁后,任何其他试图再次对互斥锁加锁的线程将会被阻塞,直到锁被释放。
互斥锁的数据类型是: pthread_mutex_t。
03. 互斥锁相关函数
3.1 互斥锁初始化
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
功能:初始化一个互斥锁。
参数:mutex:互斥锁地址。类型是 pthread_mutex_t 。attr:设置互斥量的属性,通常可采用默认属性,即可将 attr 设为 NULL。
返回值:成功:0,成功申请的锁默认是打开的。失败:非 0 错误码
可以使用宏 PTHREAD_MUTEX_INITIALIZER 静态初始化互斥锁,比如:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
这种方法等价于使用 NULL 指定的 attr 参数调用 pthread_mutex_init() 来完成动态初始化,不同之处在于 PTHREAD_MUTEX_INITIALIZER 宏不进行错误检查。
3.2 互斥锁加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:对互斥锁上锁,若互斥锁已经上锁,则调用者一直阻塞,直到互斥锁解锁后再上锁。
参数:mutex:互斥锁地址。
返回值:成功:0失败:非 0 错误码int pthread_mutex_trylock(pthread_mutex_t *mutex);
调用该函数时,若互斥锁未加锁,则上锁,返回 0;若互斥锁已加锁,则函数直接返回失败,即 EBUSY。
3.3 互斥锁解锁
int pthread_mutex_unlock(pthread_mutex_t * mutex);
功能:对指定的互斥锁解锁。
参数:mutex:互斥锁地址。
返回值:成功:0失败:非 0 错误码
3.4 互斥锁销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:销毁指定的一个互斥锁。互斥锁在使用完毕后,必须要对互斥锁进行销毁,以释放资源。
参数:mutex:互斥锁地址。
返回值:成功:0失败:非 0 错误码
04. 互斥锁示例
示例代码如下:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex; //互斥锁// 打印机
void printer(char *str)
{pthread_mutex_lock(&mutex); //上锁while(*str!='\0'){putchar(*str); fflush(stdout);str++;sleep(1);}printf("\n"); pthread_mutex_unlock(&mutex); //解锁
}// 线程一
void *thread_fun_1(void *arg)
{char *str = "hello";printer(str); //打印
}// 线程二
void *thread_fun_2(void *arg)
{char *str = "world";printer(str); //打印
}int main(void)
{pthread_t tid1, tid2;pthread_mutex_init(&mutex, NULL); //初始化互斥锁// 创建 2 个线程pthread_create(&tid1, NULL, thread_fun_1, NULL);pthread_create(&tid2, NULL, thread_fun_2, NULL);// 等待线程结束,回收其资源pthread_join(tid1, NULL);pthread_join(tid2, NULL); pthread_mutex_destroy(&mutex); //销毁互斥锁return 0;
}
测试结果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out
hello
world
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$
05. 总结
【Linux系统编程】互斥锁相关推荐
- Linux多线程编程-互斥锁
互斥锁 多线程编程中,(多线程编程)可以用互斥锁(也称互斥量)可以用来保护关键代码段,以确保其独占式的访问,这有点像二进制信号量.POSIX互斥锁相关函数主要有以下5个: #include <p ...
- Linux系统编程【文件IO、进程、进程间通信、信号、线程、互斥】
linux系统编程 个人通过学习,手打了一份48000字的Linux系统编程的笔记,包含了[文件IO.进程.进程间通信.信号.多线程.互斥]等知识点,并给出了大量的代码案例对每个重要的知识点进行了代码 ...
- 嵌入式Linux系统编程学习之二十九线程的互斥
文章目录 前言 一.创建和销毁锁 二.互斥锁属性 三.锁操作 四.加锁注意事项 五.加锁步骤 前言 在 Posix Thread 中定义了一套专门用于线程互斥的 mutex 函数.mutex 是一 ...
- linux线程并不真正并行,Linux系统编程学习札记(十二)线程1
Linux系统编程学习笔记(十二)线程1 线程1: 线程和进程类似,但是线程之间能够共享更多的信息.一个进程中的所有线程可以共享进程文件描述符和内存. 有了多线程控制,我们可以把我们的程序设计成为在一 ...
- 【Linux】一步一步学Linux系统编程教程汇总(暂时暂停更新......)
00. 目录 文章目录 00. 目录 01. 概述和标准 02. 文件操作 03. 进程概念 04. 进程间通信 05. 多线程 06. 信号 07. 同步与互斥 08. 高级IO 09. 其它 10 ...
- Linux系统编程(九)线程同步
Linux系统编程(九)线程同步 一.什么是线程同步? 二.互斥量 三.条件变量 pthread_cond_wait函数 pthread_cond_signal函数 生产者和消费者模型 一.什么是线程 ...
- 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)
文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...
- Linux系统编程笔记
文章目录 1.Linux系统编程 2.文件IO 2.1 文件描述符 2.2 open 2.3 perror 2.4 close 2.5 write 2.6 read 2.7 remove 2.8 系统 ...
- 一文带你Linux系统编程入门
文件和文件系统 文件是linux系统中最重要的抽象,大多数情况下你可以把linux系统中的任何东西都理解为文件,很多的交互操作其实都是通过文件的读写来实现的. 文件描述符 在linux内核中,文件是用 ...
- 【README】Linux系统编程必读:本专栏内容提要以及系统调用接口总结
文章目录 前言 第一部分:博客知识点 (1)基础篇 Linux系统编程1:Linux中使用率最高的一些命令 Linux系统编程2:详解Linux中的权限问题 Linux系统编程3:基础篇之详解Linu ...
最新文章
- mysql 优惠卷表设计_这些年MySQL表设计踩过的坑!
- SQL基础操作_8_基础概念
- 编程中的一种特殊递归-尾递归
- 2021“MINIEYE杯”中国大学生算法设计超级联赛(2)I love max and multiply(转化)
- STM32F0单片机快速入门八 聊聊 Coolie DMA
- luogu P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles (递推)
- 一文了解参数检验和非参数检验
- 使用linux批量引物设计,【分享】超实用的引物设计操作,一看就学会
- 什么快捷键切换仅计算机,什么是电脑屏幕切换快捷键
- 100以内的勾股数python_常见100以内勾股数
- win7自动登录(win7自动登录不用输入密码)
- CF1076C Meme Problem(韦达定理)
- RLC电阻电容电感基础知识——电容篇
- java ftp主动模式和被动模式_什么是ftp主动模式和被动模式
- .bat文件设置自动关机以及弹框确认
- adobe pdf 阅读器提示“文档证书的有效性未知。无法验证作者”
- 我,程序员,想做人工智能,可现实劝我回头是岸!
- LKD 笔记:内核同步
- S32DS配IAR for ARM编译器开发S32K14X
- mui使用百度语音合成来制作文字转语音来播放
热门文章
- 上班族的10大经典哲学,还有什么能难倒你?[轉自太平洋電腦網]
- centos配置occi环境变量_拓展学习-golang的下载、安装和环境配置教程
- mysql数据库在什么上运行_mysql – 在所有数据库上运行SQL查询
- Java黑皮书课后题第1章:1.3(显示图案)编写程序,显示下面的图案 Java
- oracle 9i rac Linux,请教高手!能在linux下安装两套oracle 9i RAC 数据库软件与实例吗?...
- 淘宝2011.9.21校园招聘会笔试题
- python array 使用创建10万浮点数
- 机器学习实战 - 读书笔记(04) - 朴素贝叶斯
- linux系统下开机启动流程
- 位向量 补码与无符号 加法与乘法 CSAPP学习笔记