信号量相关函数原型

获得一个信号量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 

最新文章

  1. web.xml中welcome-file-list的作用
  2. float导致父级元素塌陷的问题
  3. Mvc public virtual DbQuery&lt;TResult&gt; Include(&quot;&quot;)
  4. Python3利用BeautifulSoup4批量抓取站点图片的代码
  5. 【转】同一台Windows机器中启动多个Memcached服务
  6. Linux下查看文件和文件夹大小
  7. android 拨号
  8. 黄聪:在WordPress后台文章编辑器的上方或下方添加提示内容
  9. DHTMLX 前端框架 建立你的一个应用程序 教程(六)-- 表格加载数据
  10. 关于iOS上的对象映射公用方法-备
  11. Cmake 脚本对预处理器的宏定义
  12. DEV PivotGridControl 全选行或列
  13. Java程序i学习中各阶段的建议
  14. EasyUI ComboTree无限层级异步加载示例
  15. 打印进度条&gt;&gt;&gt;&gt;
  16. django中的一对一、一对多、多对多及ForeignKey()
  17. SPOJ1557 GSS2 Can you answer these queries II 历史最值线段树
  18. 关于mapreducer 读取hbase数据 存入mysql的实现过程
  19. BugPhobia开发篇章:Beta阶段第V次Scrum Meeting
  20. (转)MySQL 线程池内幕

热门文章

  1. JVM&amp;GC
  2. 【dart学习】-- Dart之JSON
  3. ribbon学习
  4. Python之-在字典、列表、集合中刷选数据
  5. Vue.config.optionMergeStrategies 用法分析
  6. 一起探讨下POST、GET请求
  7. 剑指offer---3、按之字形顺序打印二叉树
  8. qrcode.js生成二维
  9. RabbitMQ(七)心跳控制 -- heartbeat
  10. WebBrowser是IE内置的浏览器控件