LINUX 信号基础与sem_t的使用

本文介绍了LINUX信号的基本概念,重点讲解了信号量sem_t的使用,包括有名和无名信号量的区别,sem_init初始化,sem_post和sem_wait函数的原子操作特性,以及在多线程同步中的应用。示例展示了如何通过信号量实现线程间的同步协调。

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

LINUX信号

基本知识点
在这里插入图片描述

信号量的使用

头文件
#include<semaphore.h>
sem_t 分为有名和无名
有名的sem_t通过sem_open来创建,而无名的sem_t通过sem_init的初始化。
有名和无名的sem_t主要区别:
1.效率:有名sem_t是放在文件,无名的sem_t是放在内存。
2.限制:有名的sem_t可以用来同步多线程,任意多进程,而无名的sem_t可以用来同步多进程,以及fork出来的进程间的同步。

int sem_init (sem_t *sem, int pshared, unsigned int value); 

这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。pshared参数控制着信号量的类型。如果 pshared的值是0,就表示它是当前里程的局部信号量;否则,其它进程就能够共享这个信号量。pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享,我们现在只对不让进程共享的信号量感兴趣。 (这个参数 受版本影响), pshared传递一个非零将会使函数调用失败,属于无名信号量。
value给出了信号量的初始值。

控制信号量值的函数

int sem_post(sem_t * sem);

这两个函数都要用一个由sem_init调用初始化的信号量对象的指针做参数。
sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”---即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;而同 时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。信号量的值永远会正确地加一个“2”--因为有两个线程试图改变它。
函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。int sem_post(sem_t *sem);sem_post() 成功时返回 0;错误时,信号量的值没有更改,-1 被返回,并设置errno 来指明错误。错误 EINVAL  sem 不是一个有效的信号量。  EOVERFLOW 信号量允许的最大值将要被超过。

int sem_wait(sem_t * sem);

sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对 一个值为2的信号量调用sem_wait(

`sem_timedwait` 是 Linux 系统下的 semaphore(信号量)库函数,用于在给定的时间超时后等待一个信号量变为可用。Semaphore 是一种同步机制,在并发编程中用于控制对共享资源的访问。 下面是一个简单的例子,展示了如何在 Linux使用 `sem_timedwait` 函数: ```c #include <stdio.h> #include <stdlib.h> #include <semaphore.h> #define SEMAPHORE_KEY 12345 int main() { sem_t sem; // 创建一个信号量 int result; // 初始化信号量 if (sem_init(&sem, 0, 1)) { // 第一个参数是信号量结构体,第二个表示二进制模式,第三个初始化值 perror("sem_init failed"); return -1; } // 主进程创建一个临界区并尝试获取信号量 printf("Main process attempting to acquire semaphore...\n"); struct timespec timeout = {0, 500 * 1000}; // 设置超时时间为半秒 result = sem_timedwait(&sem, &timeout); // 如果信号量未可用,则最多等待半秒 if (result == -1 && errno != ETIMEDOUT) { // ETIMEDOUT 表示超时 perror("sem_timedwait failed"); } else { printf("Got the semaphore!\n"); // 进行需要互斥操作的任务... // 当完成任务后,调用 sem_post 来释放信号sem_post(&sem); } // 最终关闭信号sem_destroy(&sem); return 0; } ``` 在这个例子中,主进程首先创建一个信号量,并设置其初始值为1(代表有一个资源)。然后尝试获取这个信号量,如果当前无可用资源则会等待半秒。当获取到信号量后,可以进入临界区执行需要互斥的操作,完成后再通过 `sem_post` 释放信号量,允许其他线程也获取该信号量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值