【Linux】线程当中的信号量

信号量

  1. 信号量原理

资源计数器(描述资源的可用情况)+PCB等待队列(当资源不可用的时候,将线程放到PCB等待队列进行一个等待)

资源计数器:执行流获取信号量

获取成功信号量计数器进行-1操作;获取失败执行流放入到PCB等待队列。

信号量的接口

  1. 初始化:int sem_init(sem_t *sem,int pshared,unsigned int value);

sem:信号量,sem_t是信号量的类型

pshared:该信号量是用于进程之间还是线程之间(0:用于线程,全局变量;非0:用于进程)

value:资源的个数,初始化信号量计数器的

  1. 等待接口:int sem_wait(sem_t *sem);

1) 对资源计数器进行-1操作

2) 判断资源计数器的值是否小于0。是则堵塞等待,将执行流放入PCB等待队列;不是则接口返回

  1. 释放接口:ubt sem_post(sem_t *sem);

1)对资源计数器进行+1操作

2)判断资源计数器的值是否小于等于0。是则通知OCB等待队列;否则不用通知

  1. 销毁接口:int sem_destroy(sem_t *sem);

代码模拟:

#include <stdio.h>
#include <semaphore.h>   //信号量的头文件
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
sem_t sem; //拥有计数器+PCB等待队列

void sigcallback(int sig){
    sem_post(&sem);
}

int main(){
    signal(2, sigcallback);
    /*
     * 为了验证 sem 的接口
     *    sem_init
     *    sem_wait
     *    sem_post
     *    sem_destroy
     * */
    sem_init(&sem, 0, 1); //信号量初始维护的资源个数为0

    sem_wait(&sem); //第一次获取信号量, 因为资源个数为1, 所以可以获取到

    printf("The code has to go here\n");

    sem_wait(&sem); //阻塞在这, 因为资源计数器的值为0, 说明资源不可用

    printf("The code would be damned if it went this far\n");
    return 0;
}

运行结果:

互斥代码模拟:

#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>

int g_tickets = 100;
sem_t g_lock;

void* thread_startA(void* arg){
    pthread_detach(pthread_self());
    while(1){
        sem_wait(&g_lock); //“加锁操作”
        if(g_tickets <= 0){
            sem_post(&g_lock); //"解锁操作"
            break;
        }
        printf("i am thread_startA %p, i have %d ticket\n", pthread_self(), g_tickets);
        g_tickets--;
        sem_post(&g_lock); //"解锁操作"
        sleep(1);
    }
}

void* thread_startB(void* arg){
    pthread_detach(pthread_self());
    while(1){
        sem_wait(&g_lock); //“加锁操作”
        if(g_tickets <= 0){
            sem_post(&g_lock); //"解锁操作"
            break;
        }
        printf("i am thread_startB %p, i have %d ticket\n", pthread_self(), g_tickets);
        g_tickets--;
        sem_post(&g_lock); //"解锁操作"
        sleep(1);
    }
}

int main(){
    sem_init(&g_lock, 0, 1);

    pthread_t tid;
    int ret = pthread_create(&tid, NULL, thread_startA, NULL);
    if(ret < 0){
        perror("pthread_create");
        return 0;
    }
    ret = pthread_create(&tid, NULL, thread_startB, NULL);
    if(ret < 0){
        perror("pthread_create");
        return 0;
    }

    while(1){
        sleep(1);
    }
    sem_destroy(&g_lock);
    return 0;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值