一、线程互斥
引入互斥(mutual exclusion)锁的目的是用来保证共享数据操作的完整性。
互斥锁主要用来保护临界资源
每个临界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源
线程必须先获得互斥锁才能访问临界资源,访问完资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止
互斥锁初始化:
int pthread_mutex_init(pthread_mutex_t*mutex, pthread_mutexattr_t*attr); pthread_mutex_t*mutex:要初始化的锁对象 pthread_mutexattr_t*attr:锁的属性 默认NULL 返回值:成功是0,失败错误码
上锁:
pthread_mutex_lock(pthread_mutex_t*mutex); pthread_mutex_t*mutex:要上锁的对象
开锁:
pthread_mutex_unlock(pthread_mutex_t*mutex); pthread_mutex_t*mutex:要开锁的对象
二、进程间通信
1、进程间通信方式
传统通信方式:
1、无名管道 在内核开辟的一个缓冲区(默认64KB) 2、有名管道 在内存中开辟一个缓冲区,且在文件系统中会生成一个管道文件 3、信号 killIPC对象
共享内存 消息队列 信号灯集套接字:
socket
2、基本术语
单工:
单向通信半双工:
可以相互通信,不能同时进行全双工:
可以同时相互通信原子操作:
不可被打断的操作
3、无名管道
单工通信,并且只适用具有亲缘关系的进程间通信;具有读端和写端。
流程:创建--->读/写----->关闭
pipe():创建无名管道
int pipe(int fd[2]); 返回值:0成功,-1失败 fd[0]:固定的读端 fd[1]:固定的写端
当读端存在时:
无名管道有空间:
空间充足:直接写入数据,write函数返回写入数据的字节数
空间不足:write会写入能够写入的数据,不保证原子操作,如果读进程不读走管道缓冲区中的数据,那么写操作将会一直阻塞。
读端不存在:
wirte出现管道破裂。
写端存在:
有数据: read直接返回实际读取的字节数。
无数据: read阻塞等待数据写入。
写端不存在:
有数据: read直接返回实际读取的字节数。
无数据:read直接返回0。
4、有名管道
无名管道只能用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围。
有名管道可以使互不相关的两个进程互相通信。有名管道可以通过路径名来指出,并且在文件系统中可见。
进程通过文件IO来操作有名管道。
有名管道遵循先进先出规则。
不支持如lseek() 操作 。
mkfifo():创建有名管道
int mkfifo(const char *filename, mode_t mode); 返回值:成功0 失败-1 const char *filename:要创建有名管道的名字 mode_t mode:管道的权限 一般为0666
5、信号通信
信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。
如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程
用户进程对信号的响应方式:
忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。
捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。
执行缺省操作:Linux对每种信号都规定了默认操作
本文详细介绍了线程互斥的概念,包括互斥锁的用途、初始化与操作,以及进程间通信的不同方式,如无名管道、有名管道和信号通信,展示了它们在多线程和进程协作中的关键作用。
962

被折叠的 条评论
为什么被折叠?



