以下是您提供的文本内容的排版整理版本。我已根据内容主题将其分为几个主要部分(互斥锁、信号量、死锁、IPC进程间通信、管道操作),并使用清晰的结构组织信息:
- 代码片段用代码块格式(指定语言为C)突出显示。
- 函数定义和步骤使用有序列表整理。
- 关键概念用加粗或小标题强调。
- 整体结构基于逻辑顺序优化,确保易读性,但未修改原始内容含义。
互斥锁机制
互斥机制确保多线程中对临界资源的排他性访问(公共资源)。框架包括定义、初始化、加锁、解锁和销毁步骤。
-
定义互斥锁:
cpthread_mutex_t mutex; // 互斥锁类型变量
-
初始化锁:
- 函数:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
- 功能:初始化已定义的互斥锁。
- 参数:
mutex
:要初始化的互斥锁指针。attr
:初始化属性值,通常为NULL
(表示默认锁)。
- 返回值:成功返回
0
,失败返回非零值。
- 函数:
-
加锁:
- 函数:
int pthread_mutex_lock(pthread_mutex_t *mutex);
- 功能:对指定代码加锁,加锁后代码为原子操作(其他线程无法访问)。
- 参数:
mutex
为互斥锁指针。 - 返回值:成功返回
0
,失败返回非零值。 - 注意:如果锁已被占用,则阻塞当前线程。
- 函数:
-
解锁:
- 函数:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
- 功能:解锁指定互斥锁。
- 参数:
mutex
为互斥锁指针。 - 返回值:成功返回
0
,失败返回非零值。 - 注意:加锁和解锁通常成对出现。
- 函数:
-
销毁锁:
- 函数:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
- 功能:销毁互斥锁。
- 参数:
mutex
为互斥锁指针。 - 返回值:成功返回
0
,失败返回非零值。
- 函数:
-
非阻塞锁(trylock):
- 函数:
int pthread_mutex_trylock(pthread_mutex_t *mutex);
- 功能:类似加锁,但不阻塞。
- 参数:
mutex
为互斥锁指针。 - 返回值:成功返回
0
,失败返回非零值(如EAGAIN
)。
- 注意:互斥锁控制排他访问,但不保证次序。
- 函数:
信号量机制(Linux线程同步)
信号量用于线程或进程间同步,分类为:
- 无名信号量:线程间通信。
- 有名信号量:进程间通信。
框架包括定义、初始化、PV操作和销毁。
-
定义信号量:
csem_t sem; // 信号量类型变量
-
初始化信号量:
- 函数:
int sem_init(sem_t *sem, int pshared, unsigned int value);
- 功能:初始化已定义的信号量。
- 参数:
sem
:信号量指针。pshared
:0
表示线程间使用,非0
表示进程间使用。value
:初始值(例如,二值信号量中,0
表示阻塞,1
表示通过)。
- 返回值:成功返回
0
,失败返回非零值。
- 函数:
-
PV操作:
- P操作(申请资源):
sem_wait(sem_t *sem);
(功能:减少信号量值,如果值为0则阻塞)。 - V操作(释放资源):
sem_post(sem_t *sem);
(功能:增加信号量值,唤醒等待线程)。 - 注意:PV操作确保同步。
- P操作(申请资源):
-
销毁信号量:
- 函数:
int sem_destroy(sem_t *sem);
- 功能:销毁信号量。
- 参数:
sem
为信号量指针。 - 返回值:成功返回
0
,失败返回非零值。
- 函数:
死锁原因与必要条件
死锁产生原因:
- 系统资源不足。
- 进程运行推进顺序不合适。
- 资源分配不当。
死锁必要条件:
- 互斥条件:一个资源每次只能被一个进程使用。
- 请求与保持条件:进程因请求资源阻塞时,对已获得资源保持不放。
- 不剥夺条件:进程已获得资源在未使用完前不能被强行剥夺。
- 循环等待条件:若干进程形成头尾相接的循环等待资源关系。
注意:如果资源充足,死锁可能性低;否则易因争夺资源发生。
IPC进程间通信分类
IPC(Inter-Process Communicate)分为三大类:
-
古老通信方式:
- 无名管道。
- 有名管道。
- 信号(唯一异步通信方式)。
-
IPC对象通信(System V):
- 消息队列(较少使用)。
- 共享内存(最高效方式)。
- 信号量集。
-
Socket通信:用于网络通信。
特例:线程信号使用sem_init
(POSIX标准)。
管道操作(有名管道)
管道操作框架:打开、读写、关闭、卸载。
-
打开有名管道:
- 函数:
int open(const char *pathname, int flags);
- 注意:
-
管道为半双工模式,打开方式决定读写端。
-
示例:
cint fd_read = open("./fifo", O_RDONLY); // 固定为读端 int fd_write = open("./fifo", O_WRONLY); // 固定为写端
-
禁止使用
O_RDWR
(读写模式)或O_CREAT
(创建选项),管道创建需用mkfifo
函数。
-
- 注意:
- 函数:
-
管道读写:
- 读操作:
read(fd_read, buff, sizeof(buff));
- 写操作:
write(fd_write, buff, sizeof(buff));
- 读操作:
-
关闭管道:
- 函数:
close(fd);
- 函数:
-
卸载管道:
- 函数:
int unlink(const char *pathname);
- 功能:移除管道文件。
- 函数: