我的编程空间,编程开发者的网络收藏夹
学习永远不晚

swoole中信号量怎么使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

swoole中信号量怎么使用

这篇文章主要介绍了swoole中信号量怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇swoole中信号量怎么使用文章都会有所收获,下面我们一起来看看吧。

在swoole中,信号量主要用来保护共享资源,使得资源在一个时刻只有一个进程;信号量的值为正的时候,说明所测试的线程可以锁定而使用,信号量的值若为0,则说明测试的线程要进入睡眠队列中,等待被唤醒。

本教程操作环境:Windows10系统、Swoole4版、DELL G3电脑

swoole中信号量的用法

信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)

所拥有。信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。

Linux提供两种信号量:

(1) 内核信号量,由内核控制路径使用

(2) 用户态进程使用的信号量,这种信号量又分为POSIX信号量和SYSTEM

V信号量。

POSIX信号量又分为有名信号量和无名信号量。

有名信号量,其值保存在文件中, 所以它可以用于线程也可以用于进程间的同步。无名

信号量,其值保存在内存中。

内核信号量

内核信号量的构成

内核信号量类似于自旋锁,因为当锁关闭着时,它不允许内核控制路径继续进行。然而,

当内核控制路径试图获取内核信号量锁保护的忙资源时,相应的进程就被挂起。只有在资源被释放时,进程才再次变为可运行。

只有可以睡眠的函数才能获取内核信号量;中断处理程序和可延迟函数都不能使用内

核信号量。

内核信号量是struct semaphore类型的对象,它在

#include <pthread.h>#include <semaphore.h>#include <sys/types.h>#include <stdio.h>#include <unistd.h>int number; // 被保护的全局变量sem_t sem_id;void* thread_one_fun(void *arg){sem_wait(&sem_id);printf("thread_one have the semaphore\n");number++;printf("number = %d\n",number);sem_post(&sem_id);}void* thread_two_fun(void *arg){sem_wait(&sem_id);printf("thread_two have the semaphore \n");number--;printf("number = %d\n",number);sem_post(&sem_id);}int main(int argc,char *argv[]){number = 1;pthread_t id1, id2;sem_init(&sem_id, 0, 1);pthread_create(&id1,NULL,thread_one_fun, NULL);pthread_create(&id2,NULL,thread_two_fun, NULL);pthread_join(id1,NULL);pthread_join(id2,NULL);printf("main,,,\n");return 0;}

上面的例程,到底哪个线程先申请到信号量资源,这是随机的。如果想要某个特定的顺

序的话,可以用2个信号量来实现。例如下面的例程是线程1先执行完,然后线程2才继

续执行,直至结束。

int number; // 被保护的全局变量sem_t sem_id1, sem_id2;void* thread_one_fun(void *arg){sem_wait(&sem_id1);printf(“thread_one have the semaphore\n”);number++;printf(“number = %d\n”,number);sem_post(&sem_id2);}void* thread_two_fun(void *arg){sem_wait(&sem_id2);printf(“thread_two have the semaphore \n”);number–;printf(“number = %d\n”,number);sem_post(&sem_id1);}int main(int argc,char *argv[]){number = 1;pthread_t id1, id2;sem_init(&sem_id1, 0, 1); // 空闲的sem_init(&sem_id2, 0, 0); // 忙的pthread_create(&id1,NULL,thread_one_fun, NULL);pthread_create(&id2,NULL,thread_two_fun, NULL);pthread_join(id1,NULL);pthread_join(id2,NULL);printf(“main,,,\n”);return 0;}

(b)无名信号量在相关进程间的同步

说是相关进程,是因为本程序中共有2个进程,其中一个是另外一个的子进程(由

fork

产生)的。

本来对于fork来说,子进程只继承了父进程的代码副本,mutex理应在父子进程

中是相互独立的两个变量,但由于在初始化mutex的时候,由pshared = 1指

定了mutex处于共享内存区域,所以此时mutex变成了父子进程共享的一个变

量。此时,mutex就可以用来同步相关进程了。

#include <semaphore.h>#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>int main(int argc, char **argv){int fd, i,count=0,nloop=10,zero=0,*ptr;sem_t mutex;//open a file and map it into memoryfd = open("log.txt",O_RDWR|O_CREAT,S_IRWXU);write(fd,&zero,sizeof(int));ptr = mmap( NULL,sizeof(int),PROT_READ |PROT_WRITE,MAP_SHARED,fd,0 );close(fd);if( sem_init(&mutex,1,1) < 0) //{perror("semaphore initilization");exit(0);}if (fork() == 0){ for (i = 0; i < nloop; i++){sem_wait(&mutex);printf("child: %d\n", (*ptr)++);sem_post(&mutex);}exit(0);}for (i = 0; i < nloop; i++){sem_wait(&mutex);printf("parent: %d\n", (*ptr)++);sem_post(&mutex);}exit(0);}

2.有名信号量

有名信号量的特点是把信号量的值保存在文件中。

这决定了它的用途非常广:既可以用于线程,也可以用于相关进程间,甚至是不相关

进程。

(a)有名信号量能在进程间共享的原因

由于有名信号量的值是保存在文件中的,所以对于相关进程来说,子进程是继承了父

进程的文件描述符,那么子进程所继承的文件描述符所指向的文件是和父进程一样的,当

然文件里面保存的有名信号量值就共享了。

(b)有名信号量相关函数说明

有名信号量在使用的时候,和无名信号量共享sem_wait和sem_post函数。

区别是有名信号量使用sem_open代替sem_init,另外在结束的时候要像关闭文件

一样去关闭这个有名信号量。

(1)打开一个已存在的有名信号量,或创建并初始化一个有名信号量。一个单一的调用就完

成了信号量的创建、初始化和权限的设置。

sem_t *sem_open(const char *name, int oflag, mode_t mode , int value);

name是文件的路径名;

Oflag 有O_CREAT或O_CREAT|EXCL两个取值;

mode_t控制新的信号量的访问权限;

Value指定信号量的初始化值。

注意:

这里的name不能写成/tmp/aaa.sem这样的格式,因为在linux下,sem都是创建

在/dev/shm目录下。你可以将name写成“/mysem”或“mysem”,创建出来的文件都

是“/dev/shm/sem.mysem”,千万不要写路径。也千万不要写“/tmp/mysem”之类的。

当oflag = O_CREAT时,若name指定的信号量不存在时,则会创建一个,而且后

面的mode和value参数必须有效。若name指定的信号量已存在,则直接打开该信号量,

同时忽略mode和value参数。

当oflag = O_CREAT|O_EXCL时,若name指定的信号量已存在,该函数会直接返

回error。

(2) 一旦你使用了信号量,销毁它们就变得很重要。

在做这个之前,要确定所有对这个有名信号量的引用都已经通过sem_close()函数

关闭了,然后只需在退出或是退出处理函数中调用sem_unlink()去删除系统中的信号量,

注意如果有任何的处理器或是线程引用这个信号量,sem_unlink()函数不会起到任何的作

用。

也就是说,必须是最后一个使用该信号量的进程来执行sem_unlick才有效。因为每个

信号灯有一个引用计数器记录当前的打开次数,sem_unlink必须等待这个数为0时才能把

name所指的信号灯从文件系统中删除。也就是要等待最后一个sem_close发生。

(c)有名信号量在无相关进程间的同步

前面已经说过,有名信号量是位于共享内存区的,那么它要保护的资源也必须是位于

共享内存区,只有这样才能被无相关的进程所共享。

在下面这个例子中,服务进程和客户进程都使用shmget和shmat来获取得一块共享内

存资源。然后利用有名信号量来对这块共享内存资源进行互斥保护。

File1: server.c#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <stdio.h>#include <semaphore.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#define SHMSZ 27char SEM_NAME[]= "vik";int main(){char ch;int shmid;key_t key;char *shm,*s;sem_t *mutex;//name the shared memory segmentkey = 1000;//create & initialize semaphoremutex = sem_open(SEM_NAME,O_CREAT,0644,1);if(mutex == SEM_FAILED){perror("unable to create semaphore");sem_unlink(SEM_NAME);exit(-1);}//create the shared memory segment with this keyshmid = shmget(key,SHMSZ,IPC_CREAT|0666);if(shmid<0){perror("failure in shmget");exit(-1);}//attach this segment to virtual memoryshm = shmat(shmid,NULL,0);//start writing into memorys = shm;for(ch='A';ch<='Z';ch++){sem_wait(mutex);*s++ = ch;sem_post(mutex);}//the below loop could be replaced by binary semaphorewhile(*shm != '*'){sleep(1);}sem_close(mutex);sem_unlink(SEM_NAME);shmctl(shmid, IPC_RMID, 0);exit(0);}<u>File 2: client.c</u>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <stdio.h>#include <semaphore.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#define SHMSZ 27char SEM_NAME[]= "vik";int main(){char ch;int shmid;key_t key;char *shm,*s;sem_t *mutex;//name the shared memory segmentkey = 1000;//create & initialize existing semaphoremutex = sem_open(SEM_NAME,0,0644,0);if(mutex == SEM_FAILED){perror("reader:unable to execute semaphore");sem_close(mutex);exit(-1);}//create the shared memory segment with this keyshmid = shmget(key,SHMSZ,0666);if(shmid<0){perror("reader:failure in shmget");exit(-1);}//attach this segment to virtual memoryshm = shmat(shmid,NULL,0);//start readings = shm;for(s=shm;*s!=NULL;s++){sem_wait(mutex);putchar(*s);sem_post(mutex);}//once done signal exiting of reader:This can be replaced byanother semaphore*shm = '*';sem_close(mutex);shmctl(shmid, IPC_RMID, 0);exit(0);}

SYSTEM V信号量

这是信号量值的集合,而不是单个信号量。相关的信号量操作函数由

#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <stdio.h>static int nsems;static int semflg;static int semid;int errno=0;union semun {int val;struct semid_ds *buf;unsigned short *array;}arg;int main(){struct sembuf sops[2]; //要用到两个信号量,所以要定义两个操作数组int rslt;unsigned short argarray[80];arg.array = argarray;semid = semget(IPC_PRIVATE, 2, 0666);if(semid < 0 ){printf("semget failed. errno: %d\n", errno);exit(0);}//获取0th信号量的原始值rslt = semctl(semid, 0, GETVAL);printf("val = %d\n",rslt);//初始化0th信号量,然后再读取,检查初始化有没有成功arg.val = 1; // 同一时间只允许一个占有者semctl(semid, 0, SETVAL, arg);rslt = semctl(semid, 0, GETVAL);printf("val = %d\n",rslt);sops[0].sem_num = 0;sops[0].sem_op = -1;sops[0].sem_flg = 0;sops[1].sem_num = 1;sops[1].sem_op = 1;sops[1].sem_flg = 0;rslt=semop(semid, sops, 1); //申请0th信号量,尝试锁定if (rslt < 0 ){printf("semop failed. errno: %d\n", errno);exit(0);}//可以在这里对资源进行锁定sops[0].sem_op = 1;semop(semid, sops, 1); //释放0th信号量rslt = semctl(semid, 0, GETVAL);printf("val = %d\n",rslt);rslt=semctl(semid, 0, GETALL, arg);if (rslt < 0){printf("semctl failed. errno: %d\n", errno);exit(0);}printf("val1:%d val2: %d\n",(unsigned int)argarray[0],(unsigned int)argarray[1]);if(semctl(semid, 1, IPC_RMID) == -1){Perror(“semctl failure while clearing reason”);}return(0);}

关于“swoole中信号量怎么使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“swoole中信号量怎么使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

swoole中信号量怎么使用

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

下载Word文档

猜你喜欢

swoole中信号量怎么使用

这篇文章主要介绍了swoole中信号量怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇swoole中信号量怎么使用文章都会有所收获,下面我们一起来看看吧。在swoole中,信号量主要用来保护共享资源,使得
2023-06-29

swoole-cli怎么使用

今天小编给大家分享一下swoole-cli怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。最新的swoole-cli已
2023-06-29

JavaAQS信号量Semaphore的使用

Semaphore来自于JDK1.5的JUC包,直译过来就是信号量,被作为一种多线程并发控制工具来使用。本文将详解其原理与使用方法,感兴趣的可以学习一下
2023-02-02

怎么在PHP项目中使用Swoole

这篇“怎么在PHP项目中使用Swoole”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么在PHP项目中使用Swoole”文
2023-07-05

FreeRTOS信号量API函数怎么用

这篇文章主要介绍“FreeRTOS信号量API函数怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“FreeRTOS信号量API函数怎么用”文章能帮助大家解决问题。 前言FreeRTOS的
2023-06-29

怎么理解python信号量

本篇内容介绍了“怎么理解python信号量”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!01:信号量1)概述:信号量是用来控制线程并发数的。
2023-06-01

使用Java怎么对微信公众号批量获取

今天就跟大家聊聊有关使用Java怎么对微信公众号批量获取,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。首先为代理服务器安装证书,anyproxy默认不解析https链接,安装证书后就
2023-05-30

Java中怎么实现线程间通信与信号量

Java中怎么实现线程间通信与信号量,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.信号量Semaphore先说说Semaphore,Semaphore可以控制某个资源可
2023-05-30

怎么在php中使用Swoole连接服务器

怎么在php中使用Swoole连接服务器?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。php有什么特点1、执行速度快。2、具有很好的开放性和可扩展性。3、PHP
2023-06-14

使用Swoole怎么提高Laravel性能

使用Swoole怎么提高Laravel性能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。环境1:硬件: 1 CPU, 4 Cores, 16GB MemoryMacOS 1
2023-06-15

JUC怎么模拟AND型信号量

这篇文章主要介绍“JUC怎么模拟AND型信号量”,在日常操作中,相信很多人在JUC怎么模拟AND型信号量问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JUC怎么模拟AND型信号量”的疑惑有所帮助!接下来,请跟
2023-06-16

Redisson分布式信号量RSemaphore如何使用

本文小编为大家详细介绍“Redisson分布式信号量RSemaphore如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Redisson分布式信号量RSemaphore如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一
2023-07-05

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

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

Java中怎么利用多线程信号量控制相关资源

这期内容当中小编将会给大家带来有关Java中怎么利用多线程信号量控制相关资源,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java多线程信号量如何才能更好的控制相关的数据量?这个问题需要我们就详细的介绍下
2023-06-17

Java中信号量模型的实际应用

本篇内容介绍了“Java中信号量模型的实际应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java信号量模型的工作方式如下:线程在运行的过
2023-06-17

windows中信号量和互斥量的区别是什么

本篇内容介绍了“windows中信号量和互斥量的区别是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!区别:1、互斥量用于线程的互斥,信号
2023-06-25

怎么在Swoole中调用存储过程

本篇内容介绍了“怎么在Swoole中调用存储过程”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是存储过程存储过程是数据库管理系统中的
2023-07-05

怎么使用Java中的问号与冒号

这篇文章主要介绍了怎么使用Java中的问号与冒号,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录