标签:
在 POSIX 标准中,信号量分两种,一种是无名信号量,一种是有名信号量。无名信号量一般用于线程间同步或互斥,而有名信号量一般用于进程间同步或互斥。它们的区别和管道及命名管道的区别类似,无名信号量则直接保存在内存中,而有名信号量要求创建一个文件。前面我们学习了无名信号量的使用(详情请看《无名信号量》),这里我们学习有名信号量的使用。
1)创建一个有名信号量
所需头文件:
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
当有名信号量存在时使用:
sem_t *sem_open(const char *name, int oflag);
当有名信号量不存在时使用:
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
功能:
创建一个有名信号量。
参数:
name:信号量文件名。注意,不能指定路径名。因为有名信号量,默认放在/dev/shm 里,如下图:
flags:sem_open() 函数的行为标志。
mode:文件权限(可读、可写、可执行)的设置。
value:信号量初始值。
返回值:
成功:信号量的地址
失败:SEM_FAILED
2)关闭有名信号量
所需头文件:
#include <semaphore.h>
int sem_close(sem_t *sem);
功能:
关闭有名信号量。
参数:
sem:指向信号量的指针。
返回值:
成功:0
失败:-1
3)删除有名信号量文件
所需头文件:
#include <semaphore.h>
int sem_unlink(const char *name);
功能:
删除有名信号量的文件。
参数:
name:有名信号量文件名。
返回值:
成功:0
失败:-1
4)信号量 PV 操作
用法和《POSIX 无名信号量》一样,详情请点此链接。
有名信号量实现进程间互斥功能:
-
#include<stdio.h>
-
#include<semaphore.h>
-
#include<fcntl.h>
-
#include<unistd.h>
-
#include<sys/stat.h>
-
#include<sys/types.h>
-
-
void printer(sem_t *sem, char *str)
-
{
-
sem_wait(sem);
-
while(*str!=‘\0‘)
-
{
-
putchar(*str);
-
fflush(stdout);
-
str++;
-
sleep(1);
-
}
-
printf("\n");
-
-
sem_post(sem);
-
}
-
-
int main(int argc, char *argv[])
-
{
-
pid_t pid;
-
sem_t *sem = NULL;
-
-
pid = fork();
-
if(pid<0){
-
perror("fork error");
-
-
}else if(pid == 0){
-
-
-
sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1);
-
if(sem == SEM_FAILED){
-
perror("sem_open");
-
return -1;
-
}
-
-
char *str1 = "hello";
-
printer(sem, str1);
-
-
sem_close(sem);
-
-
_exit(1);
-
}else if(pid > 0){
-
-
-
sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1);
-
if(sem == SEM_FAILED){
-
perror("sem_open");
-
return -1;
-
}
-
-
char *str2 = "world";
-
printer(sem, str2);
-
-
sem_close(sem);
-
-
wait(pid, NULL);
-
}
-
-
sem_unlink("name_sem");
-
-
return 0;
-
}
运行结果如下:
有名信号量实现进程间同步功能(print2 先打印,再到 print1 打印):
print1.c 代码如下:
-
#include <fcntl.h> /* For O_* constants */
-
#include <sys/stat.h> /* For mode constants */
-
#include <semaphore.h>
-
#include <stdio.h>
-
-
void print(sem_t *print1, sem_t *print2)
-
{
-
int i = 0;
-
while(1)
-
{
-
sem_wait(print1);
-
i++;
-
printf("int print1 i = %d\n", i);
-
sem_post(print2);
-
}
-
}
-
-
int main(int argc, char **argv)
-
{
-
sem_t *print1, *print2;
-
-
print1 = sem_open("sem_print1", O_CREAT, 0777, 0);
-
if(SEM_FAILED == print1)
-
{
-
perror("sem_open");
-
}
-
-
print2 = sem_open("sem_print2", O_CREAT, 0777, 1);
-
if(SEM_FAILED == print2)
-
{
-
perror("sem_open");
-
}
-
-
print(print1, print2);
-
-
return 0;
-
}
print2.c 代码如下:
-
#include <fcntl.h> /* For O_* constants */
-
#include <sys/stat.h> /* For mode constants */
-
#include <semaphore.h>
-
#include <stdio.h>
-
-
void print(sem_t *print1, sem_t *print2)
-
{
-
int i = 0;
-
while(1)
-
{
-
sem_wait(print2);
-
i++;
-
printf("in print2 i = %d\n", i);
-
sleep(1);
-
sem_post(print1);
-
}
-
}
-
-
int main(int argc, char **argv)
-
{
-
sem_t *print1, *print2;
-
-
print1 = sem_open("sem_print1", O_CREAT, 0777, 0);
-
if(SEM_FAILED == print1)
-
{
-
perror("sem_open");
-
}
-
-
print2 = sem_open("sem_print2", O_CREAT, 0777, 1);
-
if(SEM_FAILED == print2)
-
{
-
perror("sem_open");
-
}
-
-
print(print1, print2);
-
-
return 0;
-
}
删除有名信号量示例代码如下:
-
#include <semaphore.h>
-
#include <stdio.h>
-
-
void sem_del(char *name)
-
{
-
int ret;
-
-
ret = sem_unlink(name);
-
if(ret < 0)
-
{
-
perror("sem_unlink");
-
}
-
}
-
-
int main(int argc, char **argv)
-
{
-
sem_del("sem_print1");
-
sem_del("sem_print2");
-
-
return 0;
-
}
makefile 代码如下:
-
all:
-
gcc sem_del.c -o sem_del -lpthread
-
gcc print1.c -o print1 -lpthread
-
gcc print2.c -o print2 -lpthread
-
clean:
-
rm sem_del print1 print2
运行程序时,先把有名信号量删除(sem_del),再分别运行 print1 和 print2:
本教程示例代码下载请点此处。
转自:http://blog.csdn.net/tennysonsky/article/details/46500417
版权声明:本文为博主原创文章,未经博主允许不得转载。
进程同步与互斥:POSIX有名信号量
标签:
原文地址:http://blog.csdn.net/lianghe_work/article/details/47775833