信号量:用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有,信号量为正的时候说明它空闲。所测试的线程可以锁定它,若为0,说明他被占用,线程要进入睡眠等待被唤醒。
多个线程使用多个资源的时候,使用信号量实现线程的同步
信号量是sem_t类型
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:初始化信号量
参数:
sem:指定要初始化的信号量
pshared:0:应用于多线程
非0:多进程
value:指定了信号量的初始值
返回值:0 成功
-1 失败 errno被设置
Link with -lrt or -pthread.
sem_destroy(3)
#include <semaphore.h>
int sem_destroy(sem_t *sem);
功能:销毁信号量
参数:sem:指定要销毁的信号量
返回值:0 成功
-1 错误 errno被设置
Link with -lrt or -pthread.
sem_post(3)
#include <semaphore.h>
int sem_post(sem_t *sem);
功能:信号量的值加1操作
参数:
sem:指定的信号量,就是这个信号量加1
返回值:0 成功
-1 错误 errno被设置
Link with -lrt or -pthread.
sem_wait(3)
#include <semaphore.h>
int sem_wait(sem_t *sem);
功能:信号量的值减1,如果信号量的值为0,阻塞等待
参数:指定了要设定的函数
返回值:0 成功
-1 错误 errno设置
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
Link with -lrt or -pthread.
使用信号量实现生产者和消费者的例子:
使用环状队列实现:sem.c
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
int queue[5];//定义一个数组用于队列
sem_t p,c;//两个信号量,一个是头,一个是尾
//生产者
void *product(void *arg){
int rear = 0;
while(1) {
//检测是否可以生产
sem_wait(&p);//????
queue[rear] = rand() % 1000 + 1;
printf("p:%d\n",queue[rear]);
//可消费数增加
sem_post(&c);//????
rear = (rear + 1) % 5;
sleep(rand()%5);
}
}
//消费者
void *consume(void *arg) {
int front = 0,tmp;
while(1) {
//检测队列中是否有数据
//没有数据就等待
sem_wait(&c);//????? 等待信号的到来,信号到来大于0执行下面并减1,等于0阻塞继续等待
tmp = queue[front];
queue[front] = -1;
sem_post(&p);//????? 将信号的值加1
printf("c:%d\n", tmp);//要消费的量一般先给中间变量
front = (front + 1) % 5;
sleep(rand()%5);
}
}
int main(void) {
pthread_t pid, cid;
//初始化信号量
sem_init(&p,0,5);
sem_init(&c,0,0);
//创建两个线程
pthread_create(&pid,NULL,product,NULL);
pthread_create(&cid,NULL,consume,NULL);
//等待两个线程的汇合
pthread_join(pid,NULL);
pthread_join(cid,NULL);
//销毁信号量
sem_destroy(&p);
sem_destroy(&c);
return 0;
}
【C语言】【unix c】信号量
最新推荐文章于 2024-08-19 19:58:43 发布