【C语言】【unix c】信号量

110 篇文章 1 订阅
信号量:用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有,信号量为正的时候说明它空闲。所测试的线程可以锁定它,若为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;
            }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘星燎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值