LinuxC/C++编程(5)—SystemV信号量
2016-05-25 18:33
337 查看
Linux中有多种类型的信号量,其中SystemV是比较重要的一种,常用于多进程同步和进程间通信。常用的函数均包含于<sys/sem.h>中。
参考了一篇很不错的博客文章:点击打开链接
自己写了一个程序,两个进程分别向控制台打印字符串,两个进程几乎一样,只是B进程中没有初始化/删除信号量。
贴代码:
这是A进程,信号量在这个进程中被初始化和删除
这是B进程,在这个进程中没有信号量的初始化函数,所以这个函数需要先在后台运行,然后再运行A进程(否则这个B进程会因为信号量未被初始化而一直被阻塞)
运行过程如下:先后台运行B进程,再运行A进程
lin@lin-Z97-HD3:~/workspace$ ./B &
[1] 9733
lin@lin-Z97-HD3:~/workspace$ ./A
b0 1.87174
a0 0.274022
b1 0.902205
a1 0.555554
b2 1.49148
a2 0.541172
b3 1.86328
a3 1.59087
b4 1.99479
a4 1.65941
b5 0.353798
a5 0.54769
b6 0.637533
a6 1.29195
b7 0.618795
a7 1.9387
b8 0.38083
a8 1.70235
b9 0.727489
a9 0.851653
[1]+ 已完成 ./B
可以看到两个进程轮流向控制台打印字符串
参考了一篇很不错的博客文章:点击打开链接
自己写了一个程序,两个进程分别向控制台打印字符串,两个进程几乎一样,只是B进程中没有初始化/删除信号量。
贴代码:
这是A进程,信号量在这个进程中被初始化和删除
//============================================================================ // Name : A.cpp // Author : Lin // Version : // Copyright : Your copyright notice // Description : A demo for processes synchronization using SystemV //============================================================================ #include <iostream> #include <unistd.h> #include <string> #include <sys/sem.h> #include <time.h> #include <stdlib.h> using namespace std; union semun { int val; struct semid_ds *buf; unsigned short *arry; }; /*******这个子函数用于创建信号量*******/ int createSem() { int semId = semget((key_t)1234, 1, 0666|IPC_CREAT);//包含于<sys/sem.h>,创建一个信号量,共用一个key_t key即表示共用一个信号量 if (semId < 0) { cerr << "create SystemV error! "<< endl; return -1; } else return semId; } /*******这个子函数用于初始化信号量*******/ int setSem(int semId) { union semun se; se.val = 1;//设置信号量的初始值为1 if (semctl(semId, 0, SETVAL, se) == -1)//初始化这个信号量 { cerr << "init fail!" << endl; return -1; } else return 0; } /*******这个子函数删除信号量*******/ int delSem(int semId) { union semun se; if (semctl(semId, 0, IPC_RMID, se) < 0) { cerr << "delete fail!" << endl; return -1; } else return 0; } /*******信号量P(等待)V(发布)操作*******/ int P_Sem(int semId) { struct sembuf buf; buf.sem_num = 0;//操作单个信号量的时候该参数为0 buf.sem_op = -1; //-1表示P操作,1表示V操作 buf.sem_flg = SEM_UNDO; if (semop(semId, &buf, 1) < 0) { cerr << "P error!" << endl; return -1; } else return 0; } int V_Sem(int semId) { struct sembuf buf; buf.sem_num = 0;//操作单个信号量的时候该参数为0 buf.sem_op = 1; //-1表示P操作,1表示V操作 buf.sem_flg = SEM_UNDO; if (semop(semId, &buf, 1) < 0) { cerr << "V error!" << endl; return -1; } else return 0; } /*******主函数*******/ int main() { string str = "a"; int semId = createSem(); if (semId == -1) return -1; if (setSem(semId) == -1) //一个信号量只能被初始化/删除一次 return -1; double d = 0; srand(time(NULL)); //设置随机数的种子 for (int i = 0; i != 10; ++i) { P_Sem(semId); //进入临界区 d = rand()*1.0/RAND_MAX; //产生一个0-1之间的随机数,让线程休眠这段时间 cout << str << i << " " << d << endl; sleep(d); V_Sem(semId); //离开临界区 } P_Sem(semId); if (delSem(semId) == -1) //一个信号量只能被初始化/删除一次 return -1; return 0; }
这是B进程,在这个进程中没有信号量的初始化函数,所以这个函数需要先在后台运行,然后再运行A进程(否则这个B进程会因为信号量未被初始化而一直被阻塞)
//============================================================================ // Name : B.cpp // Author : Lin // Version : // Copyright : Your copyright notice // Description : A demo for processes synchronization using SystemV //============================================================================ #include <iostream> #include <unistd.h> #include <string> #include <sys/sem.h> #include <stdlib.h> #include <time.h> using namespace std; union semun { int val; struct semid_ds *buf; unsigned short *arry; }; /*******这个子函数用于创建信号量*******/ int createSem() { int semId = semget((key_t)1234, 1, 0666|IPC_CREAT);//包含于<sys/sem.h>,创建一个信号量,共用一个key_t key即表示共用一个信号量 if (semId < 0) { cerr << "create SystemV error! "<< endl; return -1; } else return semId; } /*******这个子函数用于初始化信号量*******/ int setSem(int semId) { union semun se; se.val = 1;//设置信号量的初始值为1 if (semctl(semId, 0, SETVAL, se) == -1)//初始化这个信号量 { cerr << "init fail!" << endl; return -1; } else return 0; } /*******这个子函数删除信号量*******/ int delSem(int semId) { union semun se; if (semctl(semId, 0, IPC_RMID, se) < 0) { cerr << "delete fail!" << endl; return -1; } else return 0; } /*******信号量P(等待)V(发布)操作*******/ int P_Sem(int semId) { struct sembuf buf; buf.sem_num = 0;//操作单个信号量的时候该参数为0 buf.sem_op = -1; //-1表示P操作,1表示V操作 buf.sem_flg = SEM_UNDO; if (semop(semId, &buf, 1) < 0) { cerr << "P error!" << endl; return -1; } else return 0; } int V_Sem(int semId) { struct sembuf buf; buf.sem_num = 0;//操作单个信号量的时候该参数为0 buf.sem_op = 1; //-1表示P操作,1表示V操作 buf.sem_flg = SEM_UNDO; if (semop(semId, &buf, 1) < 0) { cerr << "V error!" << endl; return -1; } else return 0; } /*******主函数*******/ int main() { string str = "b"; int semId = createSem(); if (semId == -1) return -1; double d = 0; srand(time(NULL)); //设置随机数的种子 for (int i = 0; i != 10; ++i) { P_Sem(semId); //进入临界区 d = rand()*2.0/RAND_MAX; cout << str << i << " " << d << endl; sleep(d); V_Sem(semId); //离开临界区 } return 0; }
运行过程如下:先后台运行B进程,再运行A进程
lin@lin-Z97-HD3:~/workspace$ ./B &
[1] 9733
lin@lin-Z97-HD3:~/workspace$ ./A
b0 1.87174
a0 0.274022
b1 0.902205
a1 0.555554
b2 1.49148
a2 0.541172
b3 1.86328
a3 1.59087
b4 1.99479
a4 1.65941
b5 0.353798
a5 0.54769
b6 0.637533
a6 1.29195
b7 0.618795
a7 1.9387
b8 0.38083
a8 1.70235
b9 0.727489
a9 0.851653
[1]+ 已完成 ./B
可以看到两个进程轮流向控制台打印字符串
相关文章推荐
- Linux命令
- Linux定时任务crontab执行脚本出错
- Linux CentOS6.5下编译安装MySQL 5.6.16
- linux下rm命令删除文件名中包含特殊字符的文件【转】
- CentOS系统配置solr
- 每日一linux命令(4)-------mkdir
- CentOS系统安装JDK
- 修改svn日志信息(svn使用linux服务器)
- Linux编程基础——GDB(设置断点)
- Linux ssh免密码登录设置
- Linux系统启动流程
- linux创建自定义回收站
- linux环境下FTP搭建(初)
- Centos下英文改中文及gcc,g++,gdb以及输入法的安装
- Gnu/Linux系统C编程之 - 系统与进程信息
- Linux 安装Python/PIL模块
- ssh登录 The authenticity of host 192.168.0.xxx can't be established.
- linux下导入、导出mysql数据库命令
- Linux下C语言实现文件遍历,支持嵌套和文件数量统计
- linux内核demo