千家信息网

swoole中信号量怎么使用

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要介绍了swoole中信号量怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇swoole中信号量怎么使用文章都会有所收获,下面我们一起来看看吧。在swoo
千家信息网最后更新 2026年11月03日swoole中信号量怎么使用

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

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

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

swoole中信号量的用法

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

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

Linux提供两种信号量:

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

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

V信号量。

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

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

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

内核信号量

内核信号量的构成

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

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

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

核信号量。

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

#include #include #include #include #include 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 #include #include #include #include #include #include #include #include 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);/* create, initialize semaphore */if( sem_init(&mutex,1,1) < 0) //{perror("semaphore initilization");exit(0);}if (fork() == 0){ /* child process*/for (i = 0; i < nloop; i++){sem_wait(&mutex);printf("child: %d\n", (*ptr)++);sem_post(&mutex);}exit(0);}/* back to parent process */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 #include #include #include #include #include #include #include #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);}File 2: client.c#include #include #include #include #include #include #include #include #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 #include #include #include 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中信号量怎么使用"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

信号 信号量 进程 有名 内核 文件 线程 资源 函数 保护 内存 只有 时候 路径 两个 变量 同步 控制 测试 知识 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 喔噻互联网科技有限公司 上海喔噻互联网科技有限公司 深圳市人人互联网科技有限公司 互联网科技工作委员会 互联网科技公司的优势 互联网与科技发展 互联网科技开发公司 互联网和高科技公司 互联网科技中介 宁夏科技产业互联网案例 港股科技和互联网 浙江互联网科技研学营 河南猎农互联网科技有限公司 互联网科技革命什么开始 朱啸虎曾投资哪些互联网科技企业 广州千川互联网科技有限公司 广州百诚互联网科技有限公司官网 本届互联网大会上的黑科技 互联网时代科技型公司的机会 互联网科技大会大佬 互联网科技公司华为 互联网科技会 银优互联网科技有限公司 欧洲十大科技互联网公司 南山科技园互联网公司有哪些 互联网科技机房 上海万顺科技互联网有限公司招聘 科技和互联网行业的特点 唐山双旺合互联网科技产业园 华人运通互联网科技公司
0