Linux ——IPC 锁

本文详细介绍了Linux系统中Posix.1标准的互斥锁、条件变量、读写锁及其在进程间同步中的应用。讲解了不同类型的互斥锁(如正常、递归、错误检查)的特性,并提到了锁的初始化和销毁。此外,还探讨了Posix记录上锁、建议性锁和强制性锁的概念,以及fcntl、lockf、flock在文件锁中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最好的参考资料:

1.师从互联网。

2.UNP v2 Posix IPC的相关章节7、8、9。

3.Linux man 命令。

4.APUE 相关章节11、14。

第一条:概述

                   这里介绍的是Posix.1线程标准的:互斥锁、条件变量、读写锁。他们主要用来同步一个进程内各个线程的,如果把它们放在一个共享内存空间中,Posix允许他们用于进程间同步。如果想了解他们的实现,在libc源码的nptl文件下,你可以找到他们。

                    我同样也会介绍Posix.1标准的基础:fcntl的记录锁。Linux支持记录锁的所有形式:建议性锁、强制性锁、fcntl、lockf、flock。

                    顺便说一下,linux内核提供了类型为struct mutex的经典互斥量,以及相关API在linux/mutex.h文件里可以看到。libc未包含他们,有可移植性更好的Posix的原因把。

第二条:互斥锁和条件变量

互斥锁的主要用途:保护临界区(critical region)在任何时候只有一个线程在执行其中的代码。任何时刻只有一个线程可以锁住一个给定的互斥锁。如果这个互斥锁在共享内存区,就可以用来让进程向线程一样的同步(如果这样的话,线程的所有情况都适用进程,下文不再显示指明这点)。实质上,互斥锁的用途就是保护临界区内共享的数据。

 

互斥锁的初始化:必须在定义互斥锁时初始化。

1.静态分配可以初始化为常值PTHREAD_MUTEX_INITIALIZER(timed)。其值为:  { { 0, 0, 0, 0, 0, { 0 } } }。

其他的静态初始化方法:

PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP(recursive,锁多少次就得打开多少次)
PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP(fast,用户自己保证正确性)
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP(error check,纠错锁,线程不能去解另一个线程加上的锁)

 

NP代表 non-portable  不可移植!!

 

2.动态分配和分配在共享内存区中,运行时调用pthread_mutex_init函数初始化他。别忘记用pthread_mutex_destroy函数释放他。

 

互斥锁是协作性(cooperative)锁:通俗点说就是,每个线程都得遵守对于临界区的代码必须在获得互斥锁的前提下才可以执行的神圣约定。否则互斥锁,就只是浪费了资源的无用代码。

多个线程等在同一个互斥锁的状况:UNPv2上有这样的描述:不同线程可以有不同的优先级,同步函数(互斥锁、读写锁、信号量)将唤醒优先级最高的被阻塞的线程。

编程技巧:可以把共享数据和互斥锁放到一个结构中。

 

互斥量的类型:Posix .1定义四种类型

PTHREAD_MUTEX_NORMAL:不做任何错误检测和死锁检测。

1.同一个线程,在前一次lock操作未解锁,再次加锁,第二次加锁的进程将挂起。

2.同一个线程,解锁未上锁的互斥锁,不会报错。

 

3.一个线程解锁另外一个线程加锁的互斥锁成功!!!!!!!!(多次测试!!!)

//2.6.35内核、nptl线程库、glibc-2.12.2这个结果和这个帖子一致http://blog.youkuaiyun.com/guosha/archive/2008/10/24/3136721.aspx

4.一个线程对互斥锁加锁,另一个线程在对这个互斥锁加锁,另一个线程将会挂起。

5.调度特征是:先等待锁的进程先获得锁。

PTHREAD_MUTEX_RECURSIVE:允许同一线程在互斥量之前对该互斥量进行多次加锁,而且返回错误在出错时,用一个递

### Linux IPC 进程间通信机制 #### 一、消息队列 在Linux环境中,当遇到异常工作模式下的通信需求时,例如通过`Ctrl+C`发送中断信号给正在运行的进程,这种情况下传递的信息属于唯一的一种异步通讯方式——消息队列[^1]。消息队列允许一个或多个进程向其中放置消息,并由其他进程读取消息而无需关心对方的存在与否。 #### 二、共享内存 为了提高多进程间的通信效率,在Linux下可以利用共享内存来完成这一目标。这里提到的关键概念是:多个进程只需共用一块共享内存即可;这块共享内存在创建之初并不隶属于任何一个特定进程,而是作为一个独立实体存在于系统之中。要使不同进程能访问这段共享内存,则需将其映射至各自行为空间的相应位置上形成所谓的“内存映射区”。具体来说,这涉及到将同一块物理地址加入到各个参与通信的进程各自的虚拟地址空间里去的操作,此过程可通过调用`shmat()`函数实现[^2][^4]。 #### 三、进程控制 除了上述两种常见的IPC手段外,还有一种特殊的场景涉及到了更深层次的过程交互形式—即某个进程试图全面掌控另一些进程的行为流程(比如调试器对被测程序)。在这种情形之下,前者往往期望能够捕捉后者产生的任何陷阱事件或是异常状况并即时获取其最新动态变化情况。这类高级别的跨进程管理功能同样构成了Linux操作系统所提供的丰富IPC特性的一部分[^3]。 ```c #include <sys/ipc.h> #include <sys/shm.h> int main(){ key_t key = ftok("testfile",65); int shmid = shmget(key,1024,0666|IPC_CREAT); // 创建/获得共享内存ID char *str=(char*) shmat(shmid,(void*)0,0); // 将共享内存连接到当前进程 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值