Linux 信号量同步编程
前一篇文章概述了Linux 系统中信号量互斥编程,这篇文章正好是前一篇的姊妹篇----信号量同步。说它们是姊妹篇是因为它们都是利用了内核的信号量机制实现了进程间的通信。因为两者所解决的问题不同,因此它们使用的场景就会有所区别。
信号量互斥主要解决的问题是:进程间需要同时访问某种资源,但是它们对资源的操作会互相影响对方的操作结果,因此需要一种机制实现让进程在访问资源时能禁止其他进程访问相同的资源。而信号量同步则解决了另一个经典问题:生产者和消费者之间的协同工作问题。
首先描述一下生产者和消费者问题:进程A 负责生产产品(创建并写入文件),进程B 负责消费产品(复制文件),理想的流程是当进程A 创建并写好数据到文件以后,进程B就取走文件。但是两个进程运行时机的不确定往往让这个流程出现混乱,即进程A的生产工作还未完成(如只创建了文件但是没写入数据),进程B 就复制了文件,导致进程B 得到的是一个不完整的文件。事实上问题出现的原因就是两个进程间没有一种同步的机制。
信号量的提出就解决了这个问题。信号量的实现在前一篇文章中有详细介绍,这里只是指出运用信号量同步进程与互斥之间的不同,然后给出一个实例说明。
下面是笔者实现代码的思维导图:

与互斥不同的是,在给信号量赋初值时并不是赋值为1,而是赋值为0,并且在生产者中并没有获取信号量,而在消费者中也没有释放信号量。这样做是为了使两者的运行次序不会影响最后的结果。
可以分析:如果生产者程序先运行,它会依次创建并写入文件,假设此时消费者程序运行,但是此时信号量初值为0,因此消费者程序被挂起。当生产者程序执行完,释放信号量以后,消费者程序继续运行,最后得到正确的文件。
如果消费者程序先运行,它测试到信号量初值是0 ,因此直接被挂起,直到生产者程序运行完才继续运行,可知这样也能够得到正确的文件。
需要注意的是,在上图中的1.7 释放信号量里面,包含一个将初值置为0 的操作,这样是为了在下一次再运行这两个程序时,如果先运行消费者,初值仍然是0。
下面是笔者的测试代码:
生产者代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h> int main(int argc, char **argv)
{
int fd = ;
key_t key;
int semid;
struct sembuf ops;
//创建信号量集合
key = ftok("/home/application/semapthore",);
semid=semget(key,,IPC_CREAT); //将初值置为0
semctl(semid,,SETVAL,); //创建文件
fd = open("./product.txt",O_RDWR|O_CREAT,); //休息
sleep(); //写入数据
write(fd,"Product is finished!",); //关闭文件
close(fd); //释放信号量
ops.sem_num=;
ops.sem_op=;
ops.sem_flg = SEM_UNDO;
semop(semid,&ops,);
semctl(semid,,SETVAL,);
return ;
}
消费者代码;
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int main(int argc,char **argv)
{ key_t key;
int semid;
struct sembuf ops;
//打开信号量集合
key = ftok("/home/application/semapthore",);
semid=semget(key,,IPC_CREAT);
//获取信号量
ops.sem_num = ;
ops.sem_op = -;
ops.sem_flg = SEM_UNDO;
semop(semid,&ops,); //消费文件
system("cp ./product.txt ./comsum/"); return ;
}
Linux 信号量同步编程的更多相关文章
- Linux信号量同步共享内存实验.
Linux信号量同步共享内存实验. Linux信号量同步共享内存实验. 简述 程序流程 信号量和共享内存的系统函数 信号量系统函数及接口 共享内存系统函数及接口 写程序 读程序 简述 本文主要内容是自 ...
- Linux 信号量互斥编程
所谓信号量,其实就是一个数字.内核给这个数字赋予一定的含义,让它等于不同的值时所表示的意义不同.这样就可以用它来标示某种资源是否正被使用.信号的分类其实挺多的,主要还是二值和计数器.这里讨论二值 现在 ...
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...
- linux信号量之进程间同步
概念 linux信号量: 允许多个线程同时进入临界区,可以用于进程间的同步. 和互斥锁(mutex)的区别: 互斥锁只允许一个线程进入临界区. 所在头文件: semaphore.h 主要函数 初始化函 ...
- Linux多线程--使用信号量同步线程【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10813469 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过 ...
- Linux线程的信号量同步
信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区. 不多做解释,要使用信号量同步,需要包含头文件semaphore.h. 主要用到的函数: int ...
- 【linux草鞋应用编程系列】_3_ 进程间通信
一.进程间通信 linux下面提供了多种进程间通信的方法, 管道.信号.信号量.消息队列.共享内存.套接字等.下面我们分别 介绍管道.信号量.消息队列.共享内存. 信号和套 ...
- Linux内核同步机制
http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环 ...
- Linux下的编程实战【转】
一篇比较不错的文章, 降到了 makefile make , gcc编译器,GDB调试器, Linux文件系统,Linux文件API,.C语言库函数(C库函数的文件操作实际上是独立于具体的操作系统平台 ...
随机推荐
- 2008---2009学年(A)B)第1学期《中国近代史纲要》课程考核试卷
湖南人文科技学院公共课 2008---2009学年第1学期<中国近代史纲要>课程考核试卷(A) 考核方式: (闭卷) ...
- 修复直接删除linux系统后grub丢失错误
如果删除了系统后,grub丢失,开机出现“grub>”的话,可以用如下代码进入目标linux系统:grub>ls (hd0,X)/boot //x为目标系统所在分区 ...
- c语音中打印参数调用层级即call stack, call trace
http://stackoverflow.com/questions/105659/how-can-one-grab-a-stack-trace-in-c There's backtrace(), a ...
- hdoj 1035 Robot Motion
Robot Motion Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 【Struts2+Spring3+Hibernate3】SSH框架整合实现CRUD_1.2
作者: hzboy192@192.com Blog: http://my.csdn.net/peng_hao1988 版本总览:http://blog.csdn.net/peng_hao1988/ar ...
- nginx定时备份access访问日志并重启nginx
用.sh脚本写了备份日志脚本 其实就是转移文件改名后重新建一个空文件 mv /alidata/log/nginx/access/wxtest.log /alidata/log/nginx/access ...
- .NET中ToString()的用法
一.数字转换到字符串 格式说明符 说明 示例 输出 C 货币 2.5.ToString(& ...
- mysql添加用户权限
MySQL性能调优my.cnf详解 //登录MYSQLmysql -u root -p//创建用户insert into mysql.user(Host,User,Password) values(‘ ...
- 安卓开发中Theme.AppCompat.Light的解决方法
styles.xml中<style name="AppBaseTheme" parent="Theme.AppCompat.Light">提示如下错 ...
- HTTP 404 - 未找到文件 怎么样解决
找不到网页 您要查看的网页可能已被删除.名称已被更改,或者临时不可用. -------------------------------------------------------------- ...