转:Linux--进程间通信(信号量,共享内存)
源地址:http://www.cnblogs.com/forstudy/archive/2012/03/26/2413724.html
Linux--进程间通信(信号量,共享内存)(转)
一. 信号量
l信号量: 解决进程之间的同步与互斥的IPC机制





union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
// 将信号量sem_id设置为init_value
int init_sem(int sem_id,int init_value) {
union semun sem_union;
sem_union.val=init_value;
if (semctl(sem_id,,SETVAL,sem_union)==-) {
perror("Sem init");
exit();
}
return ;
}
// 删除sem_id信号量
int del_sem(int sem_id) {
union semun sem_union;
if (semctl(sem_id,,IPC_RMID,sem_union)==-) {
perror("Sem delete");
exit();
}
return ;
}
// 对sem_id执行p操作
int sem_p(int sem_id) {
struct sembuf sem_buf;
sem_buf.sem_num=;//信号量编号
sem_buf.sem_op=-;//P操作
sem_buf.sem_flg=SEM_UNDO;//系统退出前未释放信号量,系统自动释放
if (semop(sem_id,&sem_buf,)==-) {
perror("Sem P operation");
exit();
}
return ;
}
// 对sem_id执行V操作
int sem_v(int sem_id) {
struct sembuf sem_buf;
sem_buf.sem_num=;
sem_buf.sem_op=;//V操作
sem_buf.sem_flg=SEM_UNDO;
if (semop(sem_id,&sem_buf,)==-) {
perror("Sem V operation");
exit();
}
return ;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include "sem_com.c" #define DELAY_TIME 3 int main() {
pid_t pid;
// int sem_id;
// key_t sem_key; // sem_key=ftok(".",'a');
// 以0666且create mode创建一个信号量,返回给sem_id
// sem_id=semget(sem_key,1,0666|IPC_CREAT);
// 将sem_id设为1
// init_sem(sem_id,1); if ((pid=fork())<) {
perror("Fork error!\n");
exit();
} else if (pid==) {
// sem_p(sem_id); // P操作
printf("Child running...\n");
sleep(DELAY_TIME);
printf("Child %d,returned value:%d.\n",getpid(),pid);
// sem_v(sem_id); // V操作
exit();
} else {
// sem_p(sem_id); // P操作
printf("Parent running!\n");
sleep(DELAY_TIME);
printf("Parent %d,returned value:%d.\n",getpid(),pid);
// sem_v(sem_id); // V操作
// waitpid(pid,0,0);
// del_sem(sem_id);
exit();
} }

在以上程序注释//未去掉时,即没用信号量机制时,其结果为:

显然,此处存在竞争条件。
在以上程序注释//去掉后,即使用信号量机制,其结果为:

由于父子进程采用同一信号量且均执行各自PV操作,故必先等一个进程的V操作后,另一个进程才能工作。
二. 共享内存






eg. 下面这个例子完成:父进程从stdin读取字符串并保存到共享内存中,子进程从共享内存中读出数据并输出到stdout

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h> #define BUFFER_SIZE 2048 int main() {
pid_t pid;
int shmid;
char *shm_addr;
char flag[]="Parent";
char buff[BUFFER_SIZE];
// 创建当前进程的私有共享内存
if ((shmid=shmget(IPC_PRIVATE,BUFFER_SIZE,))<) {
perror("shmget");
exit();
} else
printf("Create shared memory: %d.\n",shmid); // ipcs 命令往标准输出写入一些关于活动进程间通信设施的信息
// -m 表示共享内存
printf("Created shared memory status:\n");
system("ipcs -m"); if((pid=fork())<) {
perror("fork");
exit();
}else if (pid==) {
// 自动分配共享内存映射地址,为可读可写,映射地址返回给shm_addr
if ((shm_addr=shmat(shmid,,))==(void*)-) {
perror("Child:shmat");
exit();
}else
printf("Child: Attach shared-memory: %p.\n",shm_addr); printf("Child Attach shared memory status:\n");
system("ipcs -m");
// 比较shm_addr,flag的长度为strlen(flag)的字符
// 当其内容相同时,返回0
// 否则返回(str1[n]-str2[n])
while (strncmp(shm_addr,flag,strlen(flag))) {
printf("Child: Waiting for data...\n");
sleep();
} strcpy(buff,shm_addr+strlen(flag));
printf("Child: Shared-memory: %s\n",buff);
// 删除子进程的共享内存映射地址
if (shmdt(shm_addr)<) {
perror("Child:shmdt");
exit();
}else
printf("Child: Deattach shared-memory.\n"); printf("Child Deattach shared memory status:\n");
system("ipcs -m"); }else{
sleep();
// 自动分配共享内存映射地址,为可读可写,映射地址返回给shm_addr
if ((shm_addr=shmat(shmid,,))==(void*)-) {
perror("Parent:shmat");
exit();
}else
printf("Parent: Attach shared-memory: %p.\n",shm_addr); printf("Parent Attach shared memory status:\n");
system("ipcs -m");
// shm_addr为flag+stdin
sleep();
printf("\nInput string:\n");
fgets(buff,BUFFER_SIZE-strlen(flag),stdin);
strncpy(shm_addr+strlen(flag),buff,strlen(buff));
strncpy(shm_addr,flag,strlen(flag));
// 删除父进程的共享内存映射地址
if (shmdt(shm_addr)<) {
perror("Parent:shmdt");
exit();
}else
printf("Parent: Deattach shared-memory.\n"); printf("Parent Deattach shared memory status:\n");
system("ipcs -m");
// 保证父进程在删除共享内存前,子进程能读到共享内存的内容
waitpid(pid,NULL,);
// 删除共享内存
if (shmctl(shmid,IPC_RMID,NULL)==-) {
perror("shmct:IPC_RMID");
exit();
}else
printf("Delete shared-memory.\n"); printf("Child Delete shared memory status:\n");
system("ipcs -m"); printf("Finished!\n");
} exit();
}


转:Linux--进程间通信(信号量,共享内存)的更多相关文章
- Linux进程间通信—使用共享内存
Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...
- Linux进程间通信——使用共享内存
一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...
- Linux进程间通信——使用共享内存(转)
一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...
- Linux进程间通信(四) - 共享内存
共享内存的优势 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只 ...
- linux进程间通信之共享内存篇
本文是对http://www.cnblogs.com/andtt/articles/2136279.html中共享内存(上)的进一步阐释说说明 1 共享内存的实现原理 共享内存是linux进程间通讯的 ...
- linux进程间通信之共享内存学习记录
进程 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed). 广义定义:进程是一个具有一定独立功能的 ...
- Linux进程间通信之共享内存
一,共享内存 内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存. 映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点 ...
- linux进程间通信同步-共享内存
参考:https://www.cnblogs.com/charlesblc/p/6142868.html 使用有名信号量,sem_open().sem_close().sem_post().sem_w ...
- Linux进程间通信(消息队列/信号量+共享内存)
写在前面 不得不说,Deadline果真是第一生产力.不过做出来的东西真的是不堪入目,于是又花了一早上重写代码. 实验内容 进程通信的邮箱方式由操作系统提供形如 send()和 receive()的系 ...
- Linux环境进程间通信(五): 共享内存(下)
linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
随机推荐
- import socketserver 模块 (27-03)
使用socketserver实现并发聊天 服务端可以比喻做一部电话. ("127.0.0.1", 8000) 比喻做服务端的一个号码. 1,server.py import soc ...
- Bootstrap——设置Tab标签切换
最近一个小项目需要用Tab标签切换显示不同div内容,用到了Bootstrap里面的东西,但是在Bootstrap3教程里却没有找到对应的代码,这里记录一下,方便以后快速查阅学习. 代码如下: < ...
- 【daydayup】ceshuChat
时时当勉励,岁月不待人.珍惜时间伐~ 先看看项目运行的效果 这个是在本地环境打开了两个8080端口进行模拟运行的. 先放下作者的开源地址:https://github.com/ceshu/ceshuC ...
- php7 mysql_pconnect() 缺失 解决方法
php7 兼容 MySQL 相关函数 PHP7 废除了 ”mysql.dll” ,推荐使用 mysqli 或者 pdo_mysql http://PHP.net/manual/zh/mysqlinfo ...
- [JZOJ4639] 【NOIP2016提高组A组7.16】Angel Beats!
题目 描述 题目大意 给你一棵树,每次询问两个点,求出这两个点的子树的重心到其中每个点的距离和. 重心的定义是到其中每个点距离和最小的点(不一定在两棵子树内) 思考历程 想想以前我是怎么求重心的呢-- ...
- 【玲珑杯 round#18 A】计算几何你瞎暴力
[Link]:http://www.ifrog.cc/acm/problem/1143?contest=1020&no=0 [Description] [Solution] 因为每个点的(xi ...
- Python-线程(1)
目录 什么是线程 进程与线程的区别 开启线程 为什么要使用线程 线程之间数据是共享的 什么是线程 线程与进程都是虚拟单位,目的是为了更好的描述某种事物 进程与线程的区别 进程:资源单位 线程:执行单位 ...
- springboot与任务(定时任务)
描述: 项目开发中经常需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息.Spring为我们提供了异步执行任务调度的方式,提供TaskExecutor .TaskScheduler ...
- python dict 实现swich
使用dict实现swich,通过不同的键映射不同的函数. swich = { 'hour1':pred.getper1htable, 'hour6':pred.getper6htable, 'hour ...
- VS2010-MFC(MFC应用程序框架分析)
转自:http://www.jizhuomi.com/software/145.html 一.SDK应用程序与MFC应用程序运行过程的对比 程序运行都要有入口函数,在之前的C++教程中都是main函数 ...