信号量:一个整数;

大于或等于0时代表可供并发进程使用的资源实体数;

小于0时代表正在等待使用临界区的进程数;

用于互斥的信号量初始值应大于0;

只能通过P、V原语操作而改变;

信号量元素组成:

1、表示信号量元素的值;

2、最后操作信号量元素的进程ID

3、等待信号量元素值+1的进程数;

4、等待信号量元素值为0的进程数;

semop操作中:sembuf结构的sem_flg成员可以为0、IPC_NOWAIT、SEM_UNDO 。为SEM_UNDO时,它将使操作系统跟踪当前进程对这个信号量的修改情况,如果这个进程在没有释放该信号量的情况下终止,操作系统将自动释放该进程持有的信号量。除非你对信号量的行为有特殊的要求,否则应该养成设置sem_flg为SEM_UNDO的好习惯。

二、主要函数

1.1 创建信号量

int semget(

key_t key, //标识信号量的关键字,有三种方法:1、使用IPC——PRIVATE让系统产生,

// 2、挑选一个随机数,3、使用ftok从文件路径名中产生

int nSemes, //信号量集中元素个数

int flag //IPC_CREAT;IPC_EXCL 只有在信号量集不存在时创建

)

成功:返回信号量句柄

失败:返回-1

1.2 使用ftok函数根据文件路径名产生一个关键字

key_t ftok(const char *pathname,int proj_id);

路径名称必须有相应权限

1.3 控制信号量

int semctl(

int semid, //信号量集的句柄

int semnum, //信号量集的元素数

int cmd, //命令

/*union senum arg */... //

)

成功:返回相应的值

失败:返回-1

命令详细说明:

cmd: IPC_RMID 删除一个信号量

IPC_EXCL 只有在信号量集不存在时创建

IPC_SET 设置信号量的许可权

SETVAL 设置指定信号量的元素的值为 agc.val

GETVAL 获得一个指定信号量的值

GETPID 获得最后操纵此元素的最后进程ID

GETNCNT 获得等待元素变为1的进程数

GETZCNT 获得等待元素变为0的进程数

union senum 定义如下:

union senum{

int val;

struct semid_ds *buf;

unsigned short * array;

}agc;

其中 semid_ds 定义如下:

struct semid_ds{

struct ipc_pem sem_pem; //operation pemission struct

time_t sem_otime; //last semop()time

time_t sem_ctime; //last time changed by semctl()

struct sem *sembase; //ptr to first semaphore in array

struct sem_queue *sem_pending; //pending operations

struct sem_queue *sem_pending_last; //last pending operations

struct sem_undo *undo; //undo requests on this arrary

unsigned short int sem_nsems; //number of semaphores in set

};

1.4 对信号量 +1 或 -1 或测试是否为0

int semop(

int semid,

struct sembuf *sops, //指向元素操作数组

unsigned short nsops //数组中元素操作的个数

)

结构 sembuf 定义

sembuf{

short int sem_num; //semaphore number

short int sem_op; //semaphore operaion

short int sem_flg //operation flag

};

三、例子:

2.1 服务器

#include

#include

#define SEGSIZE 1024

#define READTIME 1

union semun {

int val;

struct semid_ds *buf;

unsigned short *array;

} arg;

//生成信号量

int sem_creat(key_t key)

{

union semun sem;

int semid;

sem.val = 0;

semid = semget(key,1,IPC_CREAT|0666);

if (-1 == semid){

printf("create semaphore error\n");

exit(-1);

}

semctl(semid,0,SETVAL,sem);

return semid;

}

//删除信号量

void del_sem(int semid)

{

union semun sem;

sem.val = 0;

semctl(semid,0,IPC_RMID,sem);

}

//p

int p(int semid)

{

struct sembuf sops={0,+1,IPC_NOWAIT};

return (semop(semid,&sops,1));

}

//v

int v(int semid)

{

struct sembuf sops={0,-1,IPC_NOWAIT};

return (semop(semid,&sops,1));

}

int main()

{

key_t key;

int shmid,semid;

char *shm;

char msg[7] = "-data-";

char i;

struct semid_ds buf;

key = ftok("/",0);

shmid = shmget(key,SEGSIZE,IPC_CREAT|0604);

if (-1 == shmid){

printf(" create shared memory error\n");

return -1;

}

shm = (char *)shmat(shmid,0,0);

if (-1 == (int)shm){

printf(" attach shared memory error\n");

return -1;

}

semid = sem_creat(key);

for (i = 0;i <= 3;i++){

sleep(1);

p(semid);

sleep(READTIME);

msg[5] = '0' + i;

memcpy(shm,msg,sizeof(msg));

sleep(58);

v(semid);

}

shmdt(shm);

shmctl(shmid,IPC_RMID,&buf);

del_sem(semid);

return 0;

//gcc -o shm shm.c -g

}

2.2 客户端

#include

#include

#include

#define SEGSIZE 1024

#define READTIME 1

union semun {

int val;

struct semid_ds *buf;

unsigned short *array;

} arg;

// 打印程序执行时间

void out_time(void)

{

static long start = 0;

time_t tm;

if (0 == start){

tm = time(NULL);

start = (long)tm;

printf(" now start ...\n");

}

printf(" second: %ld \n",(long)(time(NULL)) - start);

}

//创建信号量

int new_sem(key_t key)

{

union semun sem;

int semid;

sem.val = 0;

semid = semget(key,0,0);

if (-1 == semid){

printf("create semaphore error\n");

exit(-1);

}

return semid;

}

//等待信号量变成0

void wait_v(int semid)

{

struct sembuf sops={0,0,0};

semop(semid,&sops,1);

}

int main(void)

{

key_t key;

int shmid,semid;

char *shm;

char msg[100];

char i;

key = ftok("/",0);

shmid = shmget(key,SEGSIZE,0);

if(-1 == shmid){

printf(" create shared memory error\n");

return -1;

}

shm = (char *)shmat(shmid,0,0);

if (-1 == (int)shm){

printf(" attach shared memory error\n");

return -1;

}

semid = new_sem(key);

for (i = 0;i < 3;i ++){

sleep(2);

wait_v(semid);

printf("Message geted is: %s \n",shm + 1);

out_time();

}

semget创建文件_linux信号灯操作相关推荐

  1. 项目下创建文件_Linux 下创建和使用交换文件

    前言:还有5天即将元旦,一元初始,如是说:新的黎明希望闪耀.今天为大家分享Linux中交换文件的使用和概念. 一,什么是 Linux 的交换文件? 交换文件允许 Linux 将磁盘空间模拟为内存,当你 ...

  2. fopen无法创建文件_Linux中一切皆文件,除了网卡

    Linux下一切皆文件的概念深入人心,除了网卡外,在Linux系统中被分为了很多种文件,它们都有各自的特点,下面列举下: Linux中除网卡外,所有东西都被归类为以下七种文件之一: 块设备文件(blo ...

  3. kali创建文件_LINUX中,创建文件夹、文件命令及清除命令。

    展开全部 假设我们在/home里创建 1.创建一个叫test的文件夹 输入 cd /home 回车 就到e5a48de588b6323131333532363134313032313635333133 ...

  4. asp.net 创建文件夹时出错:未找到路径“D:\”的一部分。(asp.net 使用 FSO)

    这些天在整一个博客程序,其中的相册功能自然就用到IO.Directory和IO.DirectoryInfo对象,这两个对象会遍历网站所在的硬盘的磁盘根目录,不巧的是,博客传到购买的虚拟主机空间后,相册 ...

  5. 计算机无法创建新文件夹,无法创建文件,教您无法新建文件夹怎么办

    在使用电脑的过程中,都遇到过电脑出现各种故障的情况,让不少的用户感到懊恼的时刻时有发生,造成非常大的不便,该怎么解决这个烦恼呢?下面,小编给大家分享无法新建文件夹的解决经验. 相信在使用电脑是一定会遇 ...

  6. python创建文件夹命令_python文件操作指令

    原文地址:http://www.cnblogs.com/rollenholt/archive/2012/04/23/2466179.html 常用的文件操作指令: python中对文件.文件夹(文件操 ...

  7. python创建文件os_Python之文件与目录操作(os、zipfile、tarfile、shutil)

    Python中可以用于对文件和目录进行操作的内置模块包括: 模块/函数名称功能描述 open()函数 文件读取或写入 os.path模块 文件路径操作 os模块 文件和目录简单操作 zipfile模块 ...

  8. [Xcode 实际操作]七、文件与数据-(2)创建文件夹

    目录:[Swift]Xcode实际操作 本文将演示如何创建文件夹. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] 1 import UIKit 2 3 class ...

  9. php文件写入生成文件,PHP 文件操作类(创建文件并写入) 生成日志

    欢迎进入Linux社区论坛,与200万技术人员互动交流 >>进入 PHP 文件操作类(创建文件并写入) 生成日志 /** * 文件操作(生成日志)支持多条插入 * (如果插入多条语句并换行 ...

最新文章

  1. 转mosquitto auth plugin 编译配置
  2. linux zipinfo 命令详解
  3. INSTALL_FAILED_MISSING_SHARED_LIBRARY + Installation failed due to: ‘null‘
  4. 皮一皮:运气差,可能说的就是这个吧...
  5. 2.2 Wrappers访问控制
  6. 习题总结(一)——硬链接,locate,chmod,家目录
  7. bzoj1036 count 树链剖分或LCT
  8. dbeaver 设置编码_物料编码管理程序
  9. AD20输出PDF 打印 位号图 焊接图
  10. RAR与ZIP区别,哪个比较好用!
  11. 4python小项目---# 体脂率计算
  12. 数学三次危机(二)毕达哥拉斯学派的数学思想
  13. 操作系统的概念、功能和目标(操作系统1)
  14. Seating Arrangement CSU - 1997 (思维题,是否存在n个数的序列,使得相邻啷个数的差绝对值大于d)
  15. 【Unity技术积累】人物移动 坦克式移动 WASD 动画
  16. 万维钢:怎样做读书笔记
  17. 苹果手机永久删除的照片怎么恢复?
  18. xpath匹配html,使用xpath获取部分字符串匹配的html标记
  19. final、finally与finalize三者的区别
  20. js 设置 输入法 状态

热门文章

  1. 仿明日方舟网页html,《明日方舟》干员列表实现
  2. android.mk编译动态库,安卓之Android.mk多文件以及动态库编译
  3. vim 批量注释代码
  4. java 动态拼接sql_动态SQL拼接工具类
  5. linux删文件进程叫什么,Linux find 查找 并删除文件 杀掉进程
  6. java对接ldap_如何使用Java操作LDAP之LDAP连接(一)
  7. 微型计算机原理sar,微机原理的题一.程序分析 1.MOV AX,80F0H MOV CL,10H SAR AX,CL ADD AX,80H...
  8. js 获取vue组件html_vue.js中怎么引入组件?
  9. 【小白学习tensorflow教程】二、TensorBoard可视化模型训练
  10. 解决 pandas 读取数据时内存过大的问题