linux IPC的信号量
信号量相关函数原型
获得一个信号量ID
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int semget(key_t key, int nsems, int semflg);
返回值:成功信号量ID,出错-
key:函数ftok返回值或IPC_PRIVATE(适合用在有亲缘关系的进程中)
nsems:新的信号量集合中要创建的信号量个数,如果不是新创建的为0
semflg: 0取信号量集标识符,若不存在则函数会报错
IPC_CREAT:当semflg&IPC_CREAT为真时,如果不存在与key值相等的信号量集,则创建。否则返回此信号量集的标识符。
IPC_CREAT|IPC_EXCL:如果不存在与key值相等的信号量集,则创建。否则存在这样的信号集报错
对信号量的多种操作
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int semctl(int semid, int semnum, int cmd, ...);
除了GETALL以外的所有命令,成功0失败-1
semid:信号量标识符
semnum:信号量集数组上的下标,表示某个信号量
cmd:下面有说明
arg:semnum联合体
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
union semun
struct semid_ds {
struct ipc_perm sem_perm; /* Ownership and permissions */
time_t sem_otime; /* Last semop time */
time_t sem_ctime; /* Last change time */
unsigned long sem_nsems; /* No. of semaphores in set */
};
struct semid_ds
下列10种命令
IPC_STAT 对此集合取semid_ds结构,并存储在arg.buf指向的结构中
IPC_SET 设置一个信号量集合的semid_ds结构中ipc_perm域的值,并从semun的buf中取出值
IPC_RMID 从内核中删除信号量集合
GETALL 从信号量集合中获取所有信号量的值,并存到semun中的指针数组
GETNCNT 返回当前等待100%自远离用的进程个数
GETPID 返回最后执行semop的进程PID
GETVAL 返回信号量集合内单个信号量的值
GETZCNT 返回当前等待100%资源利用的进程个数
SETALL 与GETALL正好相反
SETVAL 用联合体中val成员设置信号量集合中单个信号的值
cmd指令
自动执行信号量集合上的操作数组
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int semop(int semid, struct sembuf *sops, size_t nsops);
返回值:成功0出错-1
semid:信号量标识符
sops:是指向结构体数组的指针
nsops:操作结构体的数量,恒大于或等于1
sembuf结构体
struct sembuf {
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
}
struct sembuf
测试代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int semid = ; union semun {
int val;
struct semid_ds *buf;
unsigned short *arry;
}; int set_semvalue()
{
union semun sem_union; sem_union.val = ;
if(semctl(semid, , SETVAL, sem_union) == -)
return -; return ;
} void del_semvalue()
{
union semun sem_union; if(semctl(semid, , IPC_RMID, sem_union) == -)
fprintf(stderr, "Failed to delete semaphore\n");
} int P()
{
struct sembuf sem_b;
sem_b.sem_num = ;
sem_b.sem_op = -;
sem_b.sem_flg = SEM_UNDO;
if(semop(semid, &sem_b, ) == -)
{
fprintf(stderr, "P() failed\n");
return -;
}
return ;
} int V()
{
struct sembuf sem_b;
sem_b.sem_num = ;
sem_b.sem_op = ;
sem_b.sem_flg = SEM_UNDO;
if(semop(semid, &sem_b, ) == -)
{
fprintf(stderr, "V() failed\n");
return -;
}
returi ;
} int main(int argc, char *argv[])
{
char msg = 'X';
int i=; if(argc > && !strcmp(argv[], ""))
{
/* first user sem */
if(set_semvalue() == -)
{
fprintf(stderr, "Failed to initialize semaphore\n");
return -;
}
msg = argv[][];
sleep();
} semid = semget((key_t), , |IPC_CREAT);
if(semid == -)
{
printf("semget error\n");
return -;
}
for(i=;i<;i++)
{
if(P() == -)
return -;
printf("%c", msg);
fflush(stdout);
sleep(rand()%);
printf("%c", msg);
fflush(stdout);
if(V() == -)
return -;
sleep(rand()%);
}
sleep();
printf("\n%d - finished\n", getpid()); if(argc > )
del_semvalue(); return ;
}
第二个竞争了例子:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h> int main(int argc, char *argv[])
{
char msg = 'X';
int i =;
if(argc >)
msg = argv[][]; for(i=;i<;i++)
{
printf("%c", msg);
fflush(stdout);
sleep(rand()%);
printf("%c", msg);
fflush(stdout);
sleep(rand()%);
}
sleep();
printf("\n%d - finished\n", getpid());
return ;
}
运行方法:
./a.out &./a.out
linux IPC的信号量的更多相关文章
- Linux IPC POSIX 信号量
模型 #include<semaphore.h> #include<sys/stat.h> #include<fcntl.h> sem_open() //初始化并打 ...
- Linux IPC 之信号量
信号量(也叫信号灯)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语. 信号量是进程/线程同步的一种方式,有时候我们需要保护一段代码,使它每次只能被一个执行进程/线程运行,这种工作就需 ...
- 【转载】Linux的进程间通信-信号量
原文:Linux的进程间通信-信号量 Linux的进程间通信-信号量 版权声明: 本文章内容在非商业使用前提下可无需授权任意转载.发布. 转载.发布请务必注明作者和其微博.微信公众号地址,以便读者询问 ...
- System V IPC 之信号量
本文继<System V IPC 之共享内存>之后接着介绍 System V IPC 的信号量编程.在开始正式的内容前让我们先概要的了解一下 Linux 中信号量的分类. 信号量的分类 在 ...
- Linux IPC实践(1) -- 概述
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...
- linux ipc/its
linux进程间双向消息队列 server.c #include <stdio.h> #include <stdlib.h> #include <string.h> ...
- Linux多线程编程-信号量
在Linux中.信号量API有两组.一组是多进程编程中的System V IPC信号量.另外一组是我们要讨论的POSIX信号量. 这两组接口类似,但不保证互换.POSIX信号量函数都已sem_开头,并 ...
- Linux IPC之共享内存C 事例
Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报 分类: Linux(3) 读书札记(3) 版权 ...
- linux 下的信号量参数
linux 下的信号量参数 转载自:http://blog.itpub.net/26110315/viewspace-718306/ 信号量是一种锁机制用于协调进程之间互斥的访问临界资源.以确保某种共 ...
随机推荐
- Anaconda/Conda创建环境时报错的解决方案
按照Conda网站上的提示安装完Conda之后,想要用conda create创建环境,一直报错: ERROR conda.core.link:_execute_actions(337): An er ...
- Hands Off for Mac如何卸载?完全卸载Hands Off的方法
Hands Off for Mac如何卸载?hands off是一款超好用的防火墙软件,在Mac系统上强大且易用,能够控制所有应用的网络连接和文件系统访问,保护我们的隐私数据和系统安全性,如果不需要了 ...
- Delphi 版本信息获取函数 GetFileVersionInfo、GetFileVersionInfoSize、VerFindFile、VerInstallFile和VerQueryValue
一.版本信息获取函数简介和作用 获取文件版本信息的作用: 1. 避免在新版本的组件上安装旧版本的相同组件: 2. 在多语言系统环境中,操作系统根据文件版本信息里提供的语言信息在启动程序时决定使用的正确 ...
- Django--分页器(paginator)、Django的用户认证、Django的FORM表单
分页器(paginator) >>> from django.core.paginator import Paginator >>> objects = ['joh ...
- SLA(服务等级协议)
SLA:Service-Level Agreement的缩写,意思是服务等级协议.是关于网络服务供应商和客户间的一份合同,其中定义了服务类型.服务质量和客户付款等术语. 定义SLA:Service-L ...
- XAMPP安装和配置
一.XAMPP安装: 下载地址:https://www.apachefriends.org/zh_cn/index.html 二.修改MySQL数据库 1.更改Apache中数据库端口号 保存后重新启 ...
- Gson extend 思路
package org.rx.core.internal; import com.google.gson.*; import net.sf.cglib.proxy.Enhancer; import n ...
- SQLSERVER 时间日期函数,查询今天日期、昨天、一个星期、半年前的数据
今天的所有数据:select * from 表名 where DateDiff(dd,datetime类型字段,getdate())=0昨天的所有数据:select * from 表名 where D ...
- 在dos中编译java文件
首先Dos中 编译java文件是:javac (所有)类名.java 运行java文件是:java 包名.类名 java指令默认在寻找class文件的地址是通过CLASSPATH环境变量中指定的目录中 ...
- shell eval命令
1. eval command-line 其中command-line是在终端上键入的一条普通命令行.然而当在它前面放上eval时,其结果是shell在执行命令行之前扫描它两次.如: pipe=&qu ...