Linux程序设计:进程通信
日期:忘了。
关键词:Linux程序设计;System-V;进程通信;共享内存;消息队列。
一、共享内存
1.1 基本知识
(待补充)
1.2 代码
一个基于share memory实现的客户-服务模型。
- shm_comm.h
|
#define TEXT_SZ 2048 struct shared_use_st { int written_by_you; char some_text[TEXT_SZ]; }; typedef |
- shm1.c
|
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/shm.h> #include "shm_com.h"
int main() { int running = 1; void *shm_ptr = NULL; struct shared_use_st *shared_stuff; int shmid;
srand((unsigned
shmid = shmget((key_t)1234, sizeof(shared_use_st), 0666 | IPC_CREAT); printf("shmid = %x\n", shmid); if (shmid == -1) { fprintf(stderr, "shmget fail\n"); exit(EXIT_FAILURE); } shm_ptr = shmat(shmid, NULL, 0); //该值应该是shm在当前进程空间中的虚拟地址,而不是shm真实的物理地址 //所以shm1和shm2的返回值不一样
if (shm_ptr == (void *)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); }
printf("Memory attached at %p\n", shm_ptr);
shared_stuff = (struct shared_use_st *)shm_ptr; shared_stuff->written_by_you = 0; while (running) { if (shared_stuff->written_by_you) { printf("You wrote %s\n", shared_stuff->some_text); sleep(5); shared_stuff->written_by_you = 0; if (strncmp(shared_stuff->some_text, "end", 3) == 0) { running = 0; } } }
if(shmdt(shm_ptr) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); }
if(shmctl(shmid, IPC_RMID, NULL) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } |
- shm2.c
|
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/shm.h> #include "shm_com.h"
int main() { int running = 1; void *shm_ptr = NULL; struct shared_use_st *share_stuff; char buff[TEXT_SZ]; int shmid;
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT); printf("shmid = %x\n", shmid); if(shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); }
shm_ptr = shmat(shmid, NULL, 0); if(shm_ptr == (void *)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); } printf("Memory attached at %p\n", shm_ptr);
share_stuff = (struct shared_use_st*)shm_ptr;
while(running) { if(share_stuff->written_by_you == 1) { sleep(1); printf("waiting for client\n"); } printf("Enter texts:"); fgets(buff, TEXT_SZ, stdin); strncpy(share_stuff->some_text, buff, TEXT_SZ); share_stuff->written_by_you = 1; if(strncmp(share_stuff->some_text, "end", 3) == 0) { running = 0; } }
if(shmdt(shm_ptr) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS);
} |
- 运行结果

二、消息队列
2.1 基本知识
待补充。
2.2 代码
- msg1.c
|
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h>
#include <sys/msg.h> struct msg_t { long char content[BUFSIZ]; };
int main() { int running = 1; int msgid; long struct msg_t msg;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT); printf("msgid = %d\n", msgid); if (msgid == -1) { fprintf(stderr, "msgget failed\n"); exit(EXIT_FAILURE); }
while (running) { if (msgrcv(msgid, (void *)&msg, BUFSIZ, msg_to_receive, 0) == -1) { fprintf(stderr, "msgrcv failde\n"); exit(EXIT_FAILURE); } printf("You wrote %s", msg.content); if(strncmp(msg.content, "end", 3) == 0) running = 0; } if (msgctl(msgid, IPC_RMID, 0) == -1) { fprintf(stderr, "msgcntl failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS);
}
|
- msg2.c
|
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/msg.h> #define MAX_TEXT 512 struct msg_t { long char content[BUFSIZ]; };
int main() { int running = 1; struct msg_t msg; int msgid; char buffer[BUFSIZ];
msgid = msgget((key_t)1234, 0666 | IPC_CREAT); printf("msgid = %d\n", msgid);
if (msgid == -1) { fprintf(stderr, "msgget failed\n"); exit(EXIT_FAILURE); }
while (running) { printf("Enter texts:"); fgets(buffer, BUFSIZ, stdin); msg.msg_type = 1; strcpy(msg.content, buffer);
if(msgsnd(msgid, (void *)&msg, BUFSIZ, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } if(strncmp(msg.content, "end", 3) == 0) { running = 0; } }
exit(EXIT_SUCCESS); } |
三、信号量
3.1 基本知识
待补充。
3.2 代码
- semun.h
|
#if defined(__GNU_LIBRARY__) && /* union semun is defined by including <sys/sem.h> */ #else /* according to X/OPEN we have to define it ourselves */ union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned struct seminfo *__buf; /* buffer for IPC_INFO */ }; #endif
|
- sema.c
|
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/sem.h> #include "semun.h"
static static { union semun sem_union; sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return return } static { union semun sem_union; if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1) fprintf(stderr, "Fail to delete semaphore\n"); } static { struct sembuf sem_b; sem_b.sem_num = 0;//信号量编号,除非是一组信号量,否则0 sem_b.sem_op = -1;//-1操作 sem_b.sem_flg = SEM_UNDO;//与操作系统对信号量的操作相关,一般是UNDO if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "sema_p failed\n"); return } return } static { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "sema_v failed\n"); return } return }
int main(int argc, char *argv[]) { int i; int pause_time; char op_char = 'O'; srand((unsigned sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT); if (argc > 1) { if(set_semvalue() == 0) { fprintf(stderr, "init fail\n"); exit(EXIT_FAILURE); } op_char = 'X'; sleep(2); }
for (i = 0; i < 10; i++) { if (sema_p() == 0) exit(EXIT_FAILURE); printf("%c", op_char); fflush(stdout);
pause_time = rand() % 3; sleep(pause_time); printf("%c", op_char); fflush(stdout);
if (!sema_v()) exit(EXIT_FAILURE); pause_time = rand() % 2; sleep(pause_time); } printf("\n%d - finished\n", getpid()); if (argc > 1) { sleep(10); del_semvalue(); } exit(EXIT_SUCCESS); } |
Linux程序设计:进程通信的更多相关文章
- Linux下进程通信的八种方法
Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...
- Linux之进程通信20160720
好久没更新了,今天主要说一下Linux的进程通信,后续Linux方面的更新应该会变缓,因为最近在看Java和安卓方面的知识,后续会根据学习成果不断分享更新Java和安卓的方面的知识~ Linux进程通 ...
- Linux下进程通信之管道
每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把 ...
- Linux:进程通信之消息队列Message实例
/*send.c*/ /*send.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h&g ...
- Linux编程---进程通信
Linux的通信方式主要有分类有以下几种: -匿名管道和FIFO有名管道 -消息队列,信号量和共享存储 -套接字 对于套接字的进程通信,我就留在套接字的文章中再写了. 一.管道 管道是最古老的进程通信 ...
- linux之间进程通信
进程间通信方式: 同主机进程间数据交换机制: pipe(无名管道) / fifo(有名管道)/ message queue(消息队列)和共享内存. 必备基础: f ...
- [置顶] 简单解析linux下进程通信方法
linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的.而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...
- linux程序设计--进程相关的各种ID
1.调用exec函数时,目标可执行文件没有设定设置用户id. 2.调用exec函数时,目标可执行文件设定设置用户id.
- 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇
前言 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一.Android系统的运行由大量相互独立的进程相互协助来完成的,所以Android进程间通信问题,是做好Andro ...
- 进程以及进程通信(IPC)类型
这里用我有限的知识来解释同时参考了一些其他博主的子类,希望能给与一部分入门的朋友一个清晰的理解,有问题之处还请指出 首先简单谈一下什么是进程? 答:进程是装入内存运行的程序段,是许多的系统对象拥有权的 ...
随机推荐
- Android Room 学习(一)
Room简介 Room persistence库为SQLite提供了一个抽象层,以便在利用SQLite的全部功能的同时实现更强大的数据库访问. 该库可帮助您在运行应用程序的设备上创建应用程序数据的缓存 ...
- adobe cc最新版 软件安装与激活
adobe cc最新版 软件安装与激活:https://m.weike.fm/lecture/4912961 说明#:Adobe CC2017的所有软件都可以按照以上方法进行安装,如:Premier ...
- tomcat 部署swagger 请求到后端乱码
问题: @ApiOperation(value = "", notes = "查看关键词列表") @ResponseBody @RequestMapping(v ...
- leetcode142
public class Solution { public ListNode detectCycle( ListNode head ) { if( head == null || head.next ...
- 源码的excel导入导出
获取所有数据,将数据进行有序切割,在进行遍历,将其导出. //设置header header("content-type:text/html;charset=utf-8"); // ...
- C#对接JAVA系统遇到的AES加密坑
起因对接合作伙伴的系统,需要对数据进行AES加密 默认的使用了已经写好的帮助类中加密算法,发现结果不对,各种尝试改变加密模式改变向量等等折腾快一下午.最后网上查了下AES在JAVA里面的实现完整代码如 ...
- LevelDB源码分析-sstable的Block
sstable中的Block(table/block.h table/block.cc table/block_builder.h table/block_builder.cc) sstable中的b ...
- Java语法 [常识1]
1. Java 语言采用的是双字节Unicode 编码 . 2. 标识符就是变量.常量.方法[函数].枚举.类.接口等由写代码的猴子们制定的名字.构成标识符的字母均有一定的规范,Java语言中的命名规 ...
- 最适合入门的Laravel中级教程(一)
Laravel 是一个全栈框架: 我们使用 Laravel 开发业务常见有 3 个方向: 前端页面和后端逻辑混合的应用 主要是面向对 SEO 有需求的项目: 比如说新闻资讯博客文章等: 一般在控制器中 ...
- xtrabackup备份还原MySQL数据库
mysqldump 备份鉴于其自身的某些特性(锁表,本质上备份出来insert脚本或者文本,不支持差异备份),不太适合对实时性要求比较高的情况Xtrabackup可以解决mysqldump存在的上述的 ...