IO进程线程、互斥锁、进程间通信:1、无名管道,2、有名管道

一、线程互斥

引入互斥(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. 传统通信方式:

    1、无名管道  在内核开辟的一个缓冲区(默认64KB)
    2、有名管道  在内存中开辟一个缓冲区,且在文件系统中会生成一个管道文件
    3、信号     kill
  2. IPC对象

    共享内存
    消息队列
    信号灯集
  3. 套接字:

    socket

2、基本术语

  1. 单工:

    单向通信
  2. 半双工:

    可以相互通信,不能同时进行
  3. 全双工:

    可以同时相互通信
  4. 原子操作:

    不可被打断的操作

3、无名管道

单工通信,并且只适用具有亲缘关系的进程间通信;具有读端和写端。

流程:创建--->读/写----->关闭

pipe():创建无名管道

int pipe(int fd[2]);
返回值:0成功,-1失败
fd[0]:固定的读端
fd[1]:固定的写端

当读端存在时:

无名管道有空间:

  1. 空间充足:直接写入数据,write函数返回写入数据的字节数

  2. 空间不足: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对每种信号都规定了默认操作

你可能感兴趣的:(linux,数据库,flask)