• 【进程间通信】信号量


    信号量

    PV 操作

    • 计数信号量(Counting Semaphores)通常有两种操作,记做 P 和 V,V操作增加信号量 S,P操作减少信号量 S。信号量的一大特征就是它的值不能通过 PV 操作以外的方式更改。
    • wait(P操作):信号量数值减一,如果减一之后信号量数值为负,则进程进入信号量队列等待。
    • signal(V操作):信号量数值加一,如果之前信号量数值就是负的(表明有进程在等资源),则将一个进程块从信号量等待队列移到就绪队列。

    主要应用函数

    1. 函数原型:初始化或销毁信号量

    sem_init(sem_t *sem, int pshared, unsigned int value);
    sem_destroy(sem_t *sem);  //销毁信号量

    2. 函数原型:加锁调用一次相当于对sem做了-- 操作;如果sem值为0, 线程会阻塞

    sem_wait(sem_t *sem);     // 加锁。调用一次相当于对sem做了-- 操作;如果sem值为0, 线程会阻塞
    sem_trywait(sem_t *sem);  // 尝试加锁。sem == 0, 加锁失败, 不阻塞, 直接返回
    sem_post(sem_t *sem);     // 解锁 ++。对sem做了++操作

    生产者消费者信号量模型

    1. 测试代码

    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <stdio.h>
    #include <semaphore.h>
    
    #define NUM 5
    
    int queue[NUM];
    sem_t blank_number, product_number; //全局数组实现环形队列
                                        //空格子信号量、产品信号量
    
    void *producer(void *arg)
    {
      int i = 0;
      while (1)
      {
        sem_wait(&blank_number);      //产者将空格子--,为0则则塞等待
        queue[i] = rand() % 1000 + 1; //生产一个产品
        printf("-----Produce-----%d\n", queue[i]);
        sem_post(&product_number); //将产品数++
    
        i = (i + 1) % NUM; //借助小标实现环形队列
        sleep(rand() % 3);
      }
    }
    
    void *consumer(void *arg)
    {
      int i = 0;
      while (1)
      {
        sem_wait(&product_number); //消费者将产品--。为0则阻塞等待
        printf("---Consumer-----%d\n", queue[i]);
        queue[i] = 0;            //消费掉一个产品
        sem_post(&blank_number); //消费掉产品,将空格子++
    
        i = (i + 1) % NUM;
        sleep(rand() % 3);
      }
    }
    
    int main(int argc, char *arg[])
    {
      pthread_t pid, cid;
      sem_init(&blank_number, 0, NUM); //初始化空格子信号量为5
      sem_init(&product_number, 0, 0); //产品数为0
    
      pthread_create(&pid, NULL, producer, NULL);
      pthread_create(&cid, NULL, consumer, NULL);
    
      pthread_join(pid, NULL);
      pthread_join(cid, NULL);
    
      sem_destroy(&blank_number);
      sem_destroy(&product_number);
      return 0;
    }
  • 相关阅读:
    【转】Python常见web系统返回码
    【转】暴力破解无线WiFi密码
    【转】Django继承AbstractUser新建User Model时出现auth.User.groups: (fields.E304)错误
    Python去除文件中的空格、Tab键和回车
    用filter求素数
    【转】Python读取PDF文档,输出内容
    【转】RPC简单介绍
    【转】Python3使用Django2.x的settings文件详解
    Python生成随机字符串
    Python之turtle画同心圆和棋盘
  • 原文地址:https://www.cnblogs.com/sunbines/p/16472093.html
Copyright © 2020-2023  润新知