iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >怎么看待Linux 多线程中的信号量Semaphore
  • 928
分享到

怎么看待Linux 多线程中的信号量Semaphore

2023-06-15 18:06:52 928人浏览 安东尼
摘要

今天就跟大家聊聊有关怎么看待linux 多线程中的信号量Semaphore,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。理解 Semaphore,从一个好的翻译开始Semaphore

今天就跟大家聊聊有关怎么看待linux 多线程中的信号量Semaphore,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

理解 Semaphore,从一个好的翻译开始

Semaphore,对多线程有过了解的人都听说过,一般我们解释为“信号量”。可是,这个单词对我们来说还是比较陌生,它和另一个单词  Singal(信号)什么关系呢?想要真正理解这个概念,必须得从它的翻译开始。事实上,Semaphore  最好的翻译应该为“信号计数量”,承认了这一点,想必你也清楚了:它和 Signal 不是一回事!

怎么看待Linux 多线程中的信号量Semaphore
剑桥词典翻译,并不容易理解

信号:简单来说就是消息,是由用户、系统或者进程发送给目标进程的信息,用来通知目标进程某个状态的改变或系统异常,对应的是异步的场景(我之前的文章有详细介绍过)。

信号量:首先是一个变量,其次是计数器。它是多线程环境下使用的一种设施,信号量在创建时需要设置一个初始值,表示同时可以有几个任务(线程)可以访问某一块共享资源。

  • 一个任务要想访问共享资源,前提是信号量大于0,当该任务成功获得资源后,将信号量的值减 1;

  • 若当前信号量的值小于 0,表明无法获得信号量,该任务必须被挂起,等待信号量恢复为正值的那一刻;

  • 当任务执行完之后,必须释放信号量,对应操作就是信号量的值加 1。

另外,对信号量的操作(加、减)都是原子的。互斥(Mutex)就是信号量初始值为 1 时的特殊情形,即同时只能有一个任务可以访问共享资源区。

怎么看待Linux 多线程中的信号量Semaphore

Semaphore 再理解

我们来设想这样一个场景(上图):假如北京的国家大剧院有一场免费的音乐会演出,可是现在正值疫情期间,剧院规定:剧院观众总人数要限制,但是允许大家中途退场,把票给其他人,其他人可以中途进场。于是,第一批先到的人从剧院门口票箱中取到了票,然后进场欣赏演出。后到的人就因为剧院满了,在门口等待。过了一段时间,有人嫌节目太无聊了,提前退场了,退场时他把门票放回去了。这样,其他人拿着这个人的票进场了。随后,又有人退场了,但是他忘记把票放回去了。这也没关系,大不了剧院内可容纳的总人数少了一个罢了。

上面的例子中,音乐会现场就是一块共享资源区,观众就是任务(线程),而票箱中的门票数就是信号量。信号量用作并发量限制,由于总的门票数是固定的,所以不会出现音乐厅被挤爆的情况。

上述的例子中,我们允许退场的观众把票带走,这是为什么呢?因为剧院工作人员可以随时在票箱里补充些门票呀(线程生产者)。说到这,你们是不是有点似曾相识呀?对啰,就是线程池,但还是有些不同,你们自己品味吧。

Semaphore 实操练习

信号量类型为 sem_t,类型及相关操作定义在头文件 semaphore.h 中,

创建信号量

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

信号量的值加 1

int sem_post(sem_t *sem);

信号量的值减 1

int sem_wait(sem_t *sem);

信号量销毁

int sem_destroy(sem_t *sem);

具体参数含义及返回值,这里就不赘述了。下面展示了一个例子:

你总共有三种类型的下载任务(类型 id 为 1、2、3),每次从键盘读取一种类型的任务进行下载,但是 CPU 最多可以同时执行 2  个下载任务(创建两个线程)。

#include <stdio.h> #include <pthread.h> #include <semaphore.h> #define MAXNUM (2) sem_t semDownload; pthread_t a_thread, b_thread, c_thread; int g_phreadNum = 1;  void func1(void *arg) {     // 等待信号量的值 > 0     sem_wait(&semDownload);     printf("============== Downloading taskType 1 ============== \n");     sleep(5);     printf("============== Finished taskType 1 ============== \n");     g_phreadNum--;     // 等待线程结束     pthread_join(a_thread, NULL); }  void func2(void *arg) {     sem_wait(&semDownload);     printf("============== Downloading taskType 2 ============== \n");     sleep(3);     printf("============== Finished taskType 2 ============== \n");     g_phreadNum--;     pthread_join(b_thread, NULL); }  void func3(void *arg) {     sem_wait(&semDownload);     printf("============== Downloading taskType 3 ============== \n");     sleep(1);     printf("============== Finished taskType 3 ============== \n");     g_phreadNum--;     pthread_join(c_thread, NULL); }  int main() {     // 初始化信号量     sem_init(&semDownload, 0, 0);     int taskTypeId;     while (scanf("%d", &taskTypeId) != EOF)     {         // 输入 0, 测试程序是否能正常退出         if (taskTypeId == 0 && g_phreadNum <= 1)         {             break;         } else if (taskTypeId == 0)         {             printf("Can not quit, current running thread num is %d\n", g_phreadNum - 1);         }         printf("your choose Downloading taskType %d\n", taskTypeId);         // 线程数超过 2 个则不下载         if (g_phreadNum > MAXNUM)         {             printf("!!! You've reached the max number of threads !!!\n");             continue;         }         // 用户选择下载 Task         switch (taskTypeId)         {         case 1:             // 创建线程 1             pthread_create(&a_thread, NULL, func1, NULL);             // 信号量 + 1,进而触发 func1 的任务             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("!!! error taskTypeId %d !!!\n", taskTypeId);             break;         }     }     // 销毁信号量     sem_destroy(&semDownload);     return 0; }

上述例子中,采用了 pthread_join()  的方式,即子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。而线程加入还有另外一种方式:pthread_detach(),即主线程与子线程分离,主线程不用关注子线程什么时候结束,子线程结束后,资源自动回收。

程序运行结果如下:

怎么看待Linux 多线程中的信号量Semaphore

还要注意一点:pthread.h 非 linux 系统的默认库, GCc 编译参数需要手动添加选项:-lpthread、-pthread.

看完上述内容,你们对怎么看待Linux 多线程中的信号量Semaphore有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网操作系统频道,感谢大家的支持。

--结束END--

本文标题: 怎么看待Linux 多线程中的信号量Semaphore

本文链接: https://www.lsjlt.com/news/281275.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么看待Linux 多线程中的信号量Semaphore
    今天就跟大家聊聊有关怎么看待Linux 多线程中的信号量Semaphore,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。理解 Semaphore,从一个好的翻译开始Semaphore...
    99+
    2023-06-15
  • 详解java中的互斥锁信号量和多线程等待机制
    互斥锁和信号量都是操作系统中为并发编程设计基本概念,互斥锁和信号量的概念上的不同在于,对于同一个资源,互斥锁只有0和1 的概念,而信号量不止于此。也就是说,信号量可以使资源同时被多个线程访问,而互斥锁同时只能被一个线程访问互斥锁在java中...
    99+
    2023-05-31
    java 互斥锁 信号量
  • Java并发编程中Semaphore计数信号量的示例分析
    这篇文章主要为大家展示了“Java并发编程中Semaphore计数信号量的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java并发编程中Semaphore计数信号量的示例分析”这篇文章...
    99+
    2023-05-31
    java semaphore
  • Java中怎么实现线程间通信与信号量
    Java中怎么实现线程间通信与信号量,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.信号量Semaphore先说说Semaphore,Semaphore可以控制某个资源可...
    99+
    2023-05-30
    java
  • Java中怎么利用多线程信号量控制相关资源
    这期内容当中小编将会给大家带来有关Java中怎么利用多线程信号量控制相关资源,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java多线程信号量如何才能更好的控制相关的数据量?这个问题需要我们就详细的介绍下...
    99+
    2023-06-17
  • Linux中怎么查看nginx进程号
    要查看Nginx进程号,可以使用以下方法之一: 使用pgrep命令查找Nginx进程号: pgrep nginx 使用ps命...
    99+
    2024-03-06
    Linux nginx
  • linux怎么查看进程的线程
    在Linux系统中,可以使用以下命令来查看进程的线程: 使用`ps`命令结合`-eLf`选项来查看所有进程的线程: ps -eL...
    99+
    2023-10-27
    linux
  • java多线程中的并发工具类CountDownLatch,CyclicBarrier和Semaphore该怎么理解
    本篇文章给大家分享的是有关java多线程中的并发工具类CountDownLatch,CyclicBarrier和Semaphore该怎么理解,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起...
    99+
    2023-06-22
  • ​linux中怎么创建多线程
    这篇文章主要介绍了linux中怎么创建多线程的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇linux中怎么创建多线程文章都会有所收获,下面我们一起来看看吧。linux线程分为两...
    99+
    2024-04-02
  • Java中怎么实现多线程通信
    Java中怎么实现多线程通信,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。概述多线程通信问题,也就是生产者与消费者问题生产者和消费者为两个线程,两个线程在运行过程中交替睡眠,生...
    99+
    2023-06-20
  • java中多线程怎么进行通信
    今天就跟大家聊聊有关java中多线程怎么进行通信,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、概要线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线...
    99+
    2023-05-31
    java 多线程通信 ava
  • linux中怎么使用grep看进程号
    要使用grep命令来查看进程号,可以按照以下步骤进行操作:1. 打开终端窗口。2. 使用以下命令来获取进程列表:```ps aux`...
    99+
    2023-09-15
    linux
  • CentOS中怎么查看某个进程的线程数量
    CentOS中怎么查看某个进程的线程数量,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.根据进程号进行查询:# pstree -p 进程号# top -Hp ...
    99+
    2023-06-10
  • Java多线程协作作业之信号同步怎么实现
    本篇内容介绍了“Java多线程协作作业之信号同步怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、信号同步多线程很多时候是协作作业。...
    99+
    2023-06-30
  • java中的线程怎么实现等待与通知
    这篇文章给大家介绍java中的线程怎么实现等待与通知,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。关于等待/通知,要记住的关键点是:必须从同步环境内调用wait()、notify()、notifyAll()方法。线程不...
    99+
    2023-05-31
    java 线程 ava
  • Linux C中多线程与volatile变量的示例分析
    这篇文章主要介绍Linux C中多线程与volatile变量的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Linux C中多线程与volatile变量volatile 修饰的变量表示改变量的值是易变的,编译...
    99+
    2023-06-09
  • Linux中怎么查看服务的端口号
    这篇文章主要介绍“Linux中怎么查看服务的端口号”,在日常操作中,相信很多人在Linux中怎么查看服务的端口号问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux中怎么查看服务的端口号”的疑惑有所帮助!...
    99+
    2023-06-27
  • linux怎么查看端口号对应的进程
    要查看端口号对应的进程,在Linux系统上可以使用以下命令: 使用netstat命令查看端口号对应的进程: netstat -t...
    99+
    2024-03-12
    linux
  • qt的信号槽跨线程程序崩溃怎么解决
    当信号槽跨线程时,Qt提供了一些机制来确保线程安全。如果你的程序在使用跨线程的信号槽时崩溃了,你可以尝试以下方法来解决问题:1. 使...
    99+
    2023-10-18
    qt
  • Linux中怎么批量Kill掉多个进程
    本篇文章为大家展示了Linux中怎么批量Kill掉多个进程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。ps -ef|grep LOCAL=NO|grep -v grep|cut -c 9-15|x...
    99+
    2023-06-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作