POSIX 无名信号量
如果我们要解决的是一个进程内部的线程间的同步互斥,那么也许不需要使用有名信号
量,因为这些线程共享同一个内存空间,我们可以定义更加轻量化的、基于内存的(不在任
何文件系统内部)无名信号量来达到目的。
这种信号量的使用步骤是
1
,在这些线程都能访问到的区域定义这种变量(比如全局变量),类型是
sem_t
。
2
,在任何线程使用它之前,用
sem_init( )
初始化他。
3
,使用
sem_wait( )/sem_trywait( )
和
sem_post( )
来分别进行
P
、
V
操作。
4
,不再需要时,使用
sem_destroy( )
来销毁他。
无名信号量一般用在进程内的线程间,因此
pshared
参数一般都为
0
。当将此种信号
量用在进程间时,必须将他定义在各个进程都能访问的地方——比如共享内存之中
#include<stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
//定义线程间共享资源
sem_t sem;
//定义一个指针作用与线程之间的共享内存
char *mem_map=NULL;
void *function(void *arg)
{
char *msg=(char *)arg;
printf("线程号:%ld 收到参数:%s\n",pthread_self(),msg);
while (1)
{
printf("function获取资源 ");
sem_wait(&sem);
printf("function获取成功\n");
printf("msg:%s\n",mem_map);
sem_post(&sem);
usleep(1000);
}
}
int main(int argc, char const *argv[])
{
mem_map=calloc(1,32);
//初始化无名信号量 0表示线程间 ,1表示初始化资源量为1
if(sem_init(&sem, 0, 1))
{
perror("sem init error");
return -1;
}
pthread_t thread;
pthread_create(&thread, NULL,function, "Hello Gz123");
while (1)
{
printf("main获取资源 ");
sem_wait(&sem);
printf("main获取成功\n发送数据:");
fgets(mem_map,32,stdin);
printf("main 释放资源\n");
sem_post(&sem);
usleep(1000);
}
pthread_join(thread,NULL);
return 0;
}
对于我们接触过的三种信号量:system-V 信号量和 POSIX 信号量(named-sem 和 unnamed-sem),下面是他们的区别:
1
,
sys-V
信号量较古老,语法艰涩。
POSIX
信号量简单,轻量。
2
,
sys-V
信号量可以对代表多种资源的多个信号量元素同一时间进行原子性的
P/V
操作,
POSIX
信号量每次只能操作一个信号量。
3
,
sys-V
信号量和
named-sem
是系统范围的资源,进程消失之后继续存在,而
unnamed-sem
是进程范围的资源,随着进程的退出而消失。
4
,
sys-V
信号量的
P/V
操作可以对信号量元素加减大于
1
的数值,而
POSIX
信号量
每次
P/V
操作都是加减
1
。
5
,
sys-V
信号量甚至还支持撤销操作——一个进程对
sys-V
信号量进行
P/V
操作时
可以给该操作贴上需要撤销的标识,那么当进程退出之后,系统会自动撤销那些做了标识的
操作。而
POSIX
信号没有此功能。
6
,
sys-V
信号量和
named-sem
适合用在进程间同步互斥,而
unamed-sem
适合
用在线程间同步互斥。