c语言_多线程入门_信号量Semaphore

2023-05-16

也属于线程同步的一种方式

信号量 Semaphore

定义:

有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。

目的:

类似计数器,常用在多线程同步任务上,信号量可以在当前线程某个任务完成后,通知别的线程,再进行别的任务。

分类:

  • 二值信号量:信号量的值只有 0 和 1,这和互斥量很类似,若资源被锁住,信号量的值为 0,若资源可用,则信号量的值为 1;
  • 计数信号量:信号量的值在 0 到一个大于 1 的限制值之间,该计数表示可用的资源的个数。

信号量在创建时需要设置一个初始值,表示同时可以有几个任务可以访问该信号量保护的共享资源,初始值为 1 就变成互斥锁 Mutex,即同时只能有一个任务可以访问信号量保护的共享资源

函数使用


首先需要 include <semaphore.h> 这个库,没啥好说的,除非你自己实现内部函数。和互斥锁一样也是四大金刚。
sem_init
简述:_创建信号量_
第一个参数:指向的信号对象
第二个参数:控制信号量的类型,如果其值为 0,就表示信号量是当前进程的局部信号量,否则信号量就可以在多个进程间共享
第三个参数:信号量 sem 的初始值
返回值:success 为 0,failure 为 - 1


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

sem_post
简述:信号量的值加 1
第一个参数:信号量对象
返回值:success 为 0,failure 为 - 1


  
int sem_post(sem_t *sem);

sem_wait
简述:信号量的值加 - 1
第一个参数:信号量对象
返回值:success 为 0,failure 为 - 1


  
int sem_wait(sem_t *sem);

sem_destroy
简述:用完记得销毁哦~
第一个参数:信号量对象
返回值:success 为 0,failure 为 - 1


  
int sem_destroy(sem_t *sem);

举例

说明:你可以进行三个下载任务,但是最多选择同时执行二个(创建两个线程)。直接看 main 函数即可,信号量的逻辑都在里面,在实际代码中最好,所有的线程和信号量的创建、释放都要进行校验,这里为了方便阅读,减少代码行数,就不进行校验了。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <windows.h>
 
#define MAXNUM 2
sem_t semDownload;
pthread_t a_thread, b_thread, c_thread;
int g_phreadNum = 1;
 
void InputInfo(void)
{
    printf("****************************************\n");
    printf("*** which task you want to download? ***\n");
    printf("*** you can enter [1-3],[0] is done  ***\n");
    printf("****************************************\n");
}
void *func1(void *arg)
{
    //等待信号量的值>0
    sem_wait(&semDownload);
    printf("==============  Downloading Task 1  ============== \n");
    Sleep(5000);
    printf("==============    Finished Task 1   ============== \n");
    g_phreadNum--;
    //等待线程结束 
    pthread_join(a_thread, NULL);
}
 
void *func2(void *arg)
{
    sem_wait(&semDownload);
    printf("==============  Downloading Task 2  ============== \n");
    Sleep(3000);
    printf("==============    Finished Task 2   ============== \n");
    g_phreadNum--;
    pthread_join(b_thread, NULL);
}
 
void *func3(void *arg)
{
    sem_wait(&semDownload);
    printf("==============  Downloading Task 3  ============== \n");
    Sleep(1000);
    printf("==============    Finished Task 3   ============== \n");
    g_phreadNum--;
    pthread_join(c_thread, NULL);
}
 
int main()
{
    int taskNum;
    InputInfo();
 
    while (scanf("%d", &taskNum) != EOF) {
        //输入0,判断是否正常退出
        if (taskNum == 0 && g_phreadNum <= 1) {
            break;
        }
        if (taskNum == 0){
            printf("Can not quit, casue count of threads is [%d]\n", g_phreadNum - 1);
        }
                //初始化信号量
        sem_init(&semDownload, 0, 0);
        printf("your choose Downloading Task [%d]\n", taskNum);
        //线程数超过2个则不下载
        if (g_phreadNum > MAXNUM) {
            printf("!!! You've reached a limit on the number of threads !!!\n");
            continue;
        }
        //用户选择下载Task
        switch (taskNum)
        {
        case 1:
            //创建线程1
            pthread_create(&a_thread, NULL, func1, NULL);
            //信号量+1,进而触发fun1的任务
            sem_post(&semDownload);
            //总线程数+1
            g_phreadNum++;
            break;
        case 2:
            pthread_create(&b_thread, NULL, func2, NULL);
            sem_post(&semDownload);
            g_phreadNum++;
            break;
        case 3:
            pthread_create(&c_thread, NULL, func3, NULL);
            sem_post(&semDownload);
            g_phreadNum++;
            break;
        default:
            printf("!!! eroor task [%d]  !!!\n", taskNum);
            break;
        }
 
    }
 
    //销毁信号量
    sem_destroy(&semDownload);
    return 0;
}

图解

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c语言_多线程入门_信号量Semaphore 的相关文章

  • python 百度aip实现文字识别

    介绍 百度aip模块是用于实现百度云与用户接口 xff0c 简单来说就是使用百度云所拥有的人工智能模块 模块使用 pip install baidu aip 下载百度云模块 登录百度云账号 填写信息 使用官方的文档 https cloud
  • python3 实现股票监控

    实现功能 1 设置股票的卖出个买入的价格 2 程序对价格进行监控 3 当价格达到预定值时发送邮件提醒 模块安装 pip install tushare pip install pandas 如果非常慢 xff1a https blog cs
  • 【网络安全CTF】BUUCTF(Basic篇)

    Linux Labs 解题思路 xff1a 已给用户名密码 xff0c 直接用ssh工具连接即可获取flag 查找flag在跟下 提交完成 BUU LFI COURSE 1 访问链接 xff1a 为php代码审计题 xff0c 看题目要求构
  • 密码学基本概念

    密码学简介 密码是经过加密过后的口令 xff0c 是指用特定的变换对数据信息进行加密保护或者安全身份认证的物质和技术 xff0c 密码学是对安全通信技术的研究 xff0c 要能够有效的防范潜在攻击 xff0c 也就是对信息加密解密的过程 密
  • 部署在k8s上的jenkins代理端口对外开放解决方案

    前言 Jenkins服务部署在k8s集群上 xff0c 之前的项目涉及的代理节点和集群在同一个内网网段 环境 Jenkins 对应jdk版本为openjdk version 34 11 0 18 34 问题描述 Jenkins要添加外部网络
  • Qt 利用stylesheet 设置按钮五态图标

    用过Qt的相信大家都对QPushButton这个类十分熟悉 xff0c 下面将介绍一种利用setstylesheet的方式 xff0c 设置按钮的五种状态 在Qt中QPushButton在视觉上给我们有以下五种状态 xff0c 分别是nor
  • 【Go语言学习】安装与配置

    文章目录 前言一 Go语言学习站二 安装与配置1 安装2 环境变量配置3 Gland编辑器安装与配置Hello World 总结 前言 Go语言特性 Go xff0c 又称为 Golang xff0c 是一门开源的编程语言 xff0c 由
  • 【安全工具】Httpx信息收集

    文章目录 前言一 下载二 使用步骤1 帮助文档2 常用命令常用组合命令 xff1a 总结 前言 HTTPX 是一个功能强大的 HTTP 客户端工具 xff0c 用于执行各种网络任务 xff0c 例如发现 Web 应用程序漏洞 探测域名和端口
  • 【云计算】Hadoop集群安装

    文章目录 前言一 环境二 安装虚拟机及配置配置网络 三 安装Ubuntu及配置下载ISO镜像VMware安装UbuntuUbuntu配置 xff1a 配置结果IP免密登录 JAVA安装hadoop安装 xff1a 文件的作用core sit
  • 图像处理-区域标记

    图像处理 区域标记 Matlab code clc span class token punctuation span close all span class token punctuation span span class token
  • 采用傅里叶变换进行平滑操作

    采用傅里叶变换进行平滑操作 clc close all span class token punctuation span span class token function clear span all span class token
  • 变分推理-ELBO

    变分推理 ELBO 变分推理ELBO 变分推理 变分推理的原理等价于最小化KL散度 xff1a K L q
  • Bayesian Neural Network Recent Papers-贝叶斯神经网络相关研究文章

    Bayesian Neural Network Recent Papers 贝叶斯神经网络相关研究文章 MethodsVariational Inference VI Markov Chain Monte CarloMCMC 43 VIEn
  • Bayes基本概念

    Bayes基本概念 Prior 先验 xff1a p z p z p z 看到数据前的猜测 xff1b Posterior 后验 xff1a
  • vm Debian 9 做服务器

    虚拟机 xff08 vm xff09 Debian 9 做服务器 参考虚拟机Centos做服务器 参考设置静态ip和dns 安装vm 43 debian9 不多说设置中文字符 43 locale安装net tools apt get ins
  • ProXmox VE创建虚拟机

    Proxmox VE Proxmox VirtualEnvironment 是一个非常棒的集成OPENVZ支持KVM应用的环境 有方面易用的WEB界面 xff0c 基于JAVA的UI和内核接口 xff0c 可以登录到VM客户方便的操作 xf
  • 抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15%

    背景 启动是App给用户的第一印象 xff0c 对用户体验至关重要 抖音的业务迭代迅速 xff0c 如果放任不管 xff0c 启动速度会一点点劣化 为此抖音iOS客户端团队做了大量优化工作 xff0c 除了传统的修改业务代码方式 xff0c
  • supervisor安装使用

    supervisord服务进程管理器 一 安装 yum span class token function install span supervisor 二 目录及使用 安装后 1 生成 etc supervisord conf 配置文件
  • laravel引入第三方云平台及使用方法

    一 引入第三方类 1 阿里oss span class token function composer span require jacobcyl ali oss storage 2 1 2 腾讯cos span class token f
  • 在ubuntu上安装多个版本的CUDA,并且可以随时切换

    前言 实验室工作站被多人使用导致需求不同的cuda版本 xff0c 一直没找到一个完全完整靠谱的教程 xff0c 这是我参考几个博客完成测试的全过程记录 xff0c 方便以后操作 xff0c 无任何商业用途 xff0c 如有侵权 xff0c

随机推荐

  • 在CentOS运行APPIMAGE文件时提示AppImages require FUSE to run

    输入如下命令行 xff1a yum enablerepo 61 epel y install fuse sshfs install from EPEL user 61 w h o a m
  • C++中的虚函数详解

    虚函数在运行时绑定 xff0c 即运行时确定执行的函数 所谓的后期绑定就是一个基类中有一个虚函数 xff0c 而派生类中重写了这个函数 xff0c 那么调用的这个虚函数的时候根据类的实例的不同而调用不同的函数 实例化是指在面向对象的编程中
  • Android中的Log输出

    安卓系统的代码量十分庞大 xff0c 无法使用Jlink之类的工具进行单步调试 xff0c 因而日志系统十分有必要 为此 xff0c 安卓开发了Log日志类用于开发者的日常调试使用 Log中配置了五种Log类 xff0c 分别表示打印五类不
  • C++中的模板类

    什么是模板类 xff1a C 43 43 发展到一定层次后 xff0c 必然有部分代码存在仅传参的数据类型不同而内容一致的情况 因此 xff0c C 43 43 为解决此类场景 xff0c 特推出模板类的使用 模板类是一种泛型技术 xff0
  • 【C/C++】指针赋初值问题

    先说结论 xff1a 指针在使用时一定要进行初始化 一 问题来源 问题提示 xff1a null pointer dereference 此问题在编译时无误 xff0c 在运行 时出的问题 xff0c 排查起来非常头疼 一开始没头绪 xff
  • 【Linux应用编程基础】ioctl函数

    一 为什么需要ioctl函数 在裸机开发中 xff0c 应用程序直接作用于寄存器 而在Linux开发中Linux驱动与Linux应用在代码层级上是分开的 xff0c 在实际开发过程中也是分两拨人开发的 xff0c Linux驱动服务于应用
  • 【半音阶口琴】基础汇总

    一 简谱初学习 增时线 xff1a 2 后面的三个杠表示前面音符的续音 减时线 xff1a 121 表示三个音符的时值都减半 附点 xff1a 1 39 2 结合性为先结合减时线 xff0c 再结合附点 xff0c 因此1表示3 4拍 四分
  • 抖音包大小优化-资源优化

    1 概述 随着业务的快速迭代 xff0c 抖音 Android 端的包大小爆发式增长 包大小直接影响到下载转化率 推广成本 运行内存和安装时间等因素 xff0c 因此对 apk 进行瘦身是一件很有必要且收益很大的事情 apk 主要由 dex
  • 【正点原子Linux C应用编程指南】学习里程碑总结

    前言 说实话 xff0c 当阅读正点原子的这篇文档时 xff0c 带着些许失望 xff0c 并不是文档写的不好 xff0c 而是质量明显不如RTOS和裸机部分的编写 xff0c 可能是没有实践过的原因 记得朱有鹏老师之前说过 xff0c 正
  • 【上位机应用开发】Python篇 A部分

    虽是嵌入式方向 xff0c 刚毕业时一直想基于C 开发一款上位机 xff0c 没争取到 xff0c 近期偶然获取到一个用python开发的宝贵机会 xff0c 记录一下 1 用Shell命令行 VS code还是集成开发环境开发的问题 xf
  • 挂载时系统提示未找到fdisk指令

    64 通俗的讲解如何在Ubuntu系统上挂在 在学习的过程中 xff0c 总结了简介的挂在 xff0c 平时一直使用的记事本记载的 xff0c 以后会慢慢记录在上面 Ubuntu14 0 04版本虚拟机挂在U盘如何操作 先让虚拟机读取到物理
  • 微信聊天记录导出

    本文将介绍如何将微信聊天记录导出为结构化数据 所需材料 一部已经root的安卓手机带GPU的Linux电脑 整体流程如下 xff1a 数据库文件提取 使用RE管理器 xff0c 在已经root的安卓手机上 xff0c 找到如下文件 xff1
  • 详解vim插件安装及配置

    前言 vim插件依赖项安装 xff1a dnf install python future dnf install python devel dnf install ncurses dnf install cmake dnf install
  • SubliemText_3配置Java的编译环境

    Sublime Text 3 添加Java环境 最近在学习Java语言 xff0c 因为写一些基础的代码练习 xff0c 而使用sublime编辑器写代码 xff0c 因为每次运行都要在命令行执行 javac 和 java 代码 xff0c
  • JDBC的学习(01)

    关于JDBC的学习 1 JDBC的简介 JDBC Java DataBase Connectivity 是由Sun公司为简化java程序访问数据库而制定的一套面向对象的应用程序的接口 它规定了一套访问数据库的API xff0c 该API对应
  • JDBC的学习(02)

    关于JDBC的学习 xff08 2 xff09 文章目录 关于JDBC的学习 xff08 2 xff09 Blob类型和批量操作1 Blob类型操作2 批量操作 数据库事务1 事务的概念2 事务的ACID属性3 数据库的四种隔离级别数据库的
  • 吐血整理的IDEA个人配置

    IDEA的个人配置 这两天突然发现电脑的浏览器主页被捆绑成hao123的主页了 xff0c 出于各种方法都没能解决这个问题 xff0c 一气之下 xff0c 重装了系统 xff0c 由于忘记了很多软甲的配置都放在C盘下了 xff0c 导致都
  • 两个报错:Ubuntu进入root后无法使用anaconda 和Your shell has not been properly configured to use ‘conda activate‘

    这个是由于我在root权限下没有添加anaconda的路径导致的 首先先进入普通用户 xff0c 看一下自己的anaconda的路径 echo PATH 然后再进入root sudo su 查看一下root下的路径 如果缺失进行添加 exp
  • 抖音品质建设 - iOS启动优化之原理篇

    前言 启动是 App 给用户的第一印象 xff0c 启动越慢用户流失的概率就越高 xff0c 良好的启动速度是用户体验不可缺少的一环 启动优化涉及到的知识点非常多面也很广 xff0c 一篇文章难以包含全部 xff0c 所以拆分成两部分 xf
  • c语言_多线程入门_信号量Semaphore

    也属于线程同步的一种方式 信号量 Semaphore 定义 xff1a 有时被称为信号灯 xff0c 是在多线程环境下使用的一种设施 xff0c 是可以用来保证两个或多个关键代码段不被并发调用 目的 xff1a 类似计数器 xff0c 常用