实验三:Linux进程管理(HDU)
2.设计内容
把下面的几个网址的内容看懂,关于Linux的通信机制就会有个基本的了解了,后面的这几个代码也应该可以看得懂了。
- 管道通信:https://blog.csdn.net/ljianhui/article/details/10168031
- 消息队列通信:https://blog.csdn.net/ljianhui/article/details/10287879
- 共享内存通信:https://blog.csdn.net/ljianhui/article/details/10253345
2)实现一个管道通信程序。话不多说,直接贴代码。
#include <sys/sem.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/wait.h>
#define BUFFER_SIZE 8192
int pipe_used_size(int pipe[2],sem_t *pipe_mutex){
int status=0;
int count=0;
char buffer[1];
sem_wait(pipe_mutex);
while(status>=0){
status=read(pipe[0], buffer,1);
if(status>=0){count=count+1;}
}
for(int i=0;i<count;i++){
write(pipe[1],buffer,1);
}
sem_post(pipe_mutex);
printf("pipe has %dB used\n",count);
return count;
}
int pipe_left_size(int pipe[2],sem_t *pipe_mutex){
int status=0;
int count=0;
char buffer[1];
sem_wait(pipe_mutex);
while(status>=0){
status=write(pipe[1],buffer,1);
if(status>=0){count=count+1;}
}
for(int i=0;i<count;i++){
read(pipe[0], buffer,1);
}
sem_post(pipe_mutex);
printf("pipe has %dB left\n",count);
return count;
}
int main(){
int pipe_fd[2];
int status;
char buffer[BUFFER_SIZE];//会初始化为0吗?
pid_t pid1,pid2,pid3;
sem_t *pipe_mutex;
pipe_mutex = sem_open("pipe_mutex", O_CREAT | O_RDWR, 0666, 0);
int pipe_size = 0;
status = pipe(pipe_fd);
if(status == -1){
printf("create pipe failed");
exit(-1);
}
int flags = fcntl(pipe_fd[1], F_GETFL);
fcntl(pipe_fd[1], F_SETFL, flags | O_NONBLOCK);
flags = fcntl(pipe_fd[0], F_GETFL);
fcntl(pipe_fd[0], F_SETFL, flags | O_NONBLOCK);
//这一块是干什么的?就是为了实现非阻塞写,
//因为在无名管道中没有open(),但是可以通过这个中方式来设置实现非阻塞写
while(status>=0){
status = write(pipe_fd[1], buffer, 128);//怎么那个管道的最大是多大?为啥出来是653....,这个是查看默认的管道的空间大小是多少。
if(status>=1){
pipe_size += 128;
}
}
printf("pipe size:%d\n", pipe_size);
//pipe_used_size(pipe_fd,pipe_mutex);
status=0;
while(status>=0){
status = read(pipe_fd[0], buffer, 128);
}
printf("EAGAIN %d\n", EAGAIN);
/*flags = fcntl(pipe_fd[1], F_GETFL);
fcntl(pipe_fd[1], F_SETFL, flags ^ O_NONBLOCK);
flags = fcntl(pipe_fd[0], F_GETFL);
fcntl(pipe_fd[0], F_SETFL, flags ^ O_NONBLOCK);*/
status = 0;
if((pid1 = fork()) == 0){
while(status>=0){
sem_wait(pipe_mutex);
printf("child1 start writing\n");
status=write(pipe_fd[1], buffer, 128);
printf("child1 write %d\n", status);
//sleep(1);
sem_post(pipe_mutex);
}
exit(0);
}else if((pid2 = fork()) == 0){
while(status>=0){
sem_wait(pipe_mutex);
printf("child2 start writing\n");
status=write(pipe_fd[1], buffer, 2047);
printf("child2 write %d\n", status);
//sleep(1);
sem_post(pipe_mutex);
}
exit(0);
}else if((pid3 = fork()) == 0){
while(status>=0){
sem_wait(pipe_mutex);
printf("child3 start writing\n");
status=write(pipe_fd[1], buffer, 4200);
printf("child3 write %d\n", status);
//sleep(1);
sem_post(pipe_mutex);
}
exit(0);
}else{
getchar();//这个语句在这里的作用是什么?
sem_post(pipe_mutex);
wait(0);
wait(0);
wait(0);
pipe_left_size(pipe_fd,pipe_mutex);//这两个函数的作用又是什么?
sem_unlink("pipe_mutex");
}
return 0;
}
3)利用Linux的消息队列通信机制实现线程的通信,也是直接上代码。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/sem.h>
#include<sys/shm.h>
#include <fcntl.h>
#define MSG_MAX 100
struct my_msgbuf{
long int mtype;
char mtext[MSG_MAX];
};
void *sender1(){
int n;
struct my_msgbuf message;
char buf[MSG_MAX];
sem_t *mutex = sem_open("mutex", O_CREAT | O_RDWR, 0666, 0);
sem_t *sender1_over = sem_open("sender1_over", O_CREAT | O_RDWR, 0666, 0);
sem_t *receive1_over = sem_open("receive1_over", O_CREAT | O_RDWR, 0666, 0);
int msqid = msgget((key_t)8088, 0666 | IPC_CREAT);
if( msqid == -1){
printf("create failed");
exit(-1);
}
while(1){
sem_wait(mutex);
printf("sender1 wirte :");
scanf("%s", &buf);
printf("\n");
message.mtype = 1;
if(strcmp(buf,"exit") == 0){
strcpy(message.mtext,"end1");
n = msgsnd(msqid, (void *)&message, 100, 0);//还有关于这个接收消息的类型?
sem_wait(receive1_over);
n = msgrcv(msqid, (void *)&message, 100, 2, 0);
printf("%s\n", message.mtext);
sem_post(sender1_over);
sem_post(mutex);
sleep(1);
return 0;
}
else{
strcpy(message.mtext,buf);
n = msgsnd(msqid, (void *)&message, 100, 0);
sem_post(mutex);
sleep(1);
}
}
}
void *sender2(){
int n;
struct my_msgbuf message;
char buf[MSG_MAX];
sem_t *mutex = sem_open("mutex", O_CREAT | O_RDWR, 0666, 0);
sem_t *sender2_over = sem_open("sender2_over", O_CREAT | O_RDWR, 0666, 0);
sem_t *receive2_over = sem_open("receive2_over", O_CREAT | O_RDWR, 0666, 0);
int msqid = msgget((key_t)8088, 0666 | IPC_CREAT);
if( msqid == -1){
printf("create failed");
exit(-1);
}
while(1){
sem_wait(mutex);
printf("sender2 wirte :");
scanf("%s", &buf);
printf("\n");
message.mtype = 1;
if(strcmp(buf,"exit") == 0){
strcpy(message.mtext,"end2");
n = msgsnd(msqid, (void *)&message, 100, 0);
sem_wait(receive2_over);
n = msgrcv(msqid, (void *)&message, 100, 3, 0);
printf("%s\n", message.mtext);
sem_post(sender2_over);
sem_post(mutex);
sleep(1);
return 0;
}
else{
strcpy(message.mtext,buf);
n = msgsnd(msqid, (void *)&message, 100, 0);
sem_post(mutex);
sleep(1);
}
}
}
void *receive(){
int n;
int over1=0;
int over2=0;
struct my_msgbuf message;
char buf[MSG_MAX];
sem_t *sender1_over = sem_open("sender1_over", O_CREAT | O_RDWR, 0666, 0);
sem_t *receive1_over = sem_open("receive1_over", O_CREAT | O_RDWR, 0666, 0);
sem_t *sender2_over = sem_open("sender2_over", O_CREAT | O_RDWR, 0644, 0);
sem_t *receive2_over = sem_open("receive2_over", O_CREAT | O_RDWR, 0666, 0);
int msqid = msgget((key_t)8088, 0666 | IPC_CREAT);
if( msqid == -1){
printf("create failed");
exit(-1);
}
while(1){
n = msgrcv(msqid, (void *)&message, 100, 0, 0);
if(n > 0){
printf("\n receive %s\n", message.mtext);
if( strcmp(message.mtext,"end1") == 0 ){
message.mtype = 2;
strcpy(message.mtext,"over1");
n = msgsnd(msqid, (void *)&message, 100, 0);
if( n == 0 ){
sem_post(receive1_over);
sem_wait(sender1_over);
}
over1 = 1;
}else if( strcmp(message.mtext,"end2") == 0 ){
message.mtype = 3;
strcpy(message.mtext,"over2");
n = msgsnd(msqid, (void *)&message, 100, 0);
if( n == 0 ){
sem_post(receive2_over);
sem_wait(sender2_over);
}
over2 = 1;
}
}
if(over1==1 && over2==1){
msgctl(msqid, IPC_RMID, 0);
exit(0);
}
sleep(1);
}
}
int main(){
int msqid = msgget((key_t)8088, 0666 | IPC_CREAT);
msgctl(msqid, IPC_RMID, 0);
sem_unlink("mutex");
sem_unlink("sender1_over");
sem_unlink("sender2_over");
sem_unlink("receive1_over");
sem_unlink("receive2_over");
sem_t *mutex = sem_open("mutex", O_CREAT | O_RDWR, 0666, 0);
sem_t *sender1_over = sem_open("sender1_over", O_CREAT | O_RDWR, 0666, 0);
sem_t *receive1_over = sem_open("receive1_over", O_CREAT | O_RDWR, 0666, 0);
sem_t *sender2_over = sem_open("sender2_over", O_CREAT | O_RDWR, 0666, 0);
sem_t *receive2_over = sem_open("receive2_over", O_CREAT | O_RDWR, 0666, 0);
pthread_t pt1,pt2,pt3;
pthread_create(&pt1, NULL, sender1, NULL);
pthread_create(&pt2, NULL, sender2, NULL);
pthread_create(&pt3, NULL, receive, NULL);
sem_post(mutex);
pthread_join(pt1, NULL);
pthread_join(pt2, NULL);
pthread_join(pt3, NULL);
return 0;
}
4)利用Linux的共享内存通信机制实现两个进程间的通信。
//为消息接收程序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include <fcntl.h>
int main(){
char buf[50];
int shmid = shmget((key_t)8888, 50, IPC_CREAT | 0666);
sem_t *mutex1 = sem_open("mutex1", O_CREAT | O_RDWR, 0666, 0);
sem_t *mutex2 = sem_open("mutex2", O_CREAT | O_RDWR, 0666, 0);
sem_wait(mutex1);
char *m =(char *)shmat(shmid, NULL, 0);
printf("receive: %s \n",m);
strcpy(buf, "over");
memcpy(m,buf,sizeof(buf));
shmdt(shmid);
sem_post(mutex2);
return 0;
}
//为消息发送程序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include <fcntl.h>
int main(){
char buf[50];
int shmid = shmget((key_t)8888, 50, IPC_CREAT | 0666);
shmctl((key_t)8888, IPC_RMID, NULL);
sem_unlink("mutex1");
sem_unlink("mutex2");
sem_t *mutex1 = sem_open("mutex1", O_CREAT | O_RDWR, 0666, 0);
sem_t *mutex2 = sem_open("mutex2", O_CREAT | O_RDWR, 0666, 0);
shmid = shmget((key_t)8888, 50, IPC_CREAT | 0666);
if( shmid == -1){
printf("create failed");
exit(-1);
}
char *m = (char *)shmat(shmid, NULL, 0);
printf("sender writing:");
scanf("%s", buf);
memcpy(m,buf,sizeof(buf));
sem_post(mutex1);
sem_wait(mutex2);
printf("\n%s\n/", m);
shmdt(shmid);
shmctl((key_t)8888, IPC_RMID, NULL);
sem_unlink("mutex1");
sem_unlink("mutex2");
return 0;
}
实验三:Linux进程管理(HDU)的更多相关文章
- 《Linux内核设计与实现》读书笔记 第三章 进程管理
第三章进程管理 进程是Unix操作系统抽象概念中最基本的一种.我们拥有操作系统就是为了运行用户程序,因此,进程管理就是所有操作系统的心脏所在. 3.1进程 概念: 进程:处于执行期的程序.但不仅局限于 ...
- Linux内核分析——第三章 进程管理
第三章 进程管理 3.1 进程 1.进程就是处于执行期的程序:进程就是正在执行的程序代码的实时结果:进程是处于执行期的程序以及相关的资源的总称:进程包括代码段和其他资源. 线程:是在进程中活动的对象. ...
- Linux进程管理 (2)CFS调度器
关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...
- Linux进程管理 (7)实时调度
关键词:RT.preempt_count.RT patch. 除了CFS调度器之外,还包括重要的实时调度器,有两种RR和FIFO调度策略.本章只是一个简单的介绍. 更详细的介绍参考<Linux进 ...
- Linux进程管理与调度-之-目录导航【转】
转自:http://blog.csdn.net/gatieme/article/details/51456569 版权声明:本文为博主原创文章 && 转载请著名出处 @ http:// ...
- Linux性能及调优指南(翻译)之Linux进程管理
本文为IBM RedBook的Linux Performanceand Tuning Guidelines的1.1节的翻译原文地址:http://www.redbooks.ibm.com/redpap ...
- Linux进程管理专题
Linux进程管理 (1)进程的诞生介绍了如何表示进程?进程的生命周期.进程的创建等等? Linux支持多种调度器(deadline/realtime/cfs/idle),其中CFS调度器最常见.Li ...
- Linux进程管理 (1)进程的诞生
专题:Linux进程管理专题 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 L ...
- Linux 进程管理 笔记
https://www.ibm.com/developerworks/cn/linux/l-linux-process-management/index.htmlLinux 进程管理剖析 进程可以是短 ...
- 《Linux 性能及调优指南》1.1 Linux进程管理
https://blog.csdn.net/ljianhui/article/details/46718835 本文为IBM RedBook的Linux Performanceand Tuning G ...
随机推荐
- microbit之mpython的API
附录:常用API函数汇总 一.显示 display.scroll("Hello, World!") 在micro:bit点阵上滚动显示Hello, World!,其中Hello, ...
- git 版本(commit) 回退 -- 使用git reset 指令
刚刚提交了三个commit, git reflog显示如下: 最后一个commit在文件末尾加了一行:v3,以此类推: 下面,使用git reset --hard commitID来进行commit回 ...
- MySQL的统计总数count(*)与count(id)或count(字段)的之间的各自效率性能对比
执行效果: 1. count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了! 从执行计划来看,count(1)和cou ...
- 【java】javac命令在win10不可用,提示javac不是内部或外部命令,也不是可运行的程序【解决方法】
JDK安装成功,并且配置了环境变量,java命令正常可以使用,但是javac命令提示 不是内部或外部命令,也不是可运行的程序 解决方法: 产生这个问题的原因,是因为环境变量的配置中,Path中配置使用 ...
- window下使用curl操作elasticsearch
1.下载curlzip,https://curl.haxx.se/download.html; 2.解压,在bin文件夹中找到curl.exe,右键“以管理员身份运行”,cmd e: 换盘符:出现E: ...
- 开源矿工工具箱新增了ETH反抽水工具
开源矿工工具箱新增了ETH反抽水工具 —— 将决定使用Claymore挖ETH时拦截的老外的抽水归谁的权力交给矿工 众所周知,所有的挖矿辅助工具都拦截了老外的Claymore内核挖ETH时的内核开发费 ...
- 【翻译】asp.net core 3.0基本概念
这篇文章描述了开发asp.net core所需要掌握的基本概念. 原文地址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/?vie ...
- 华为方舟编译器 下载 和 LiteOS Studio Setup 2019-04-16.exe SDK下载
华为方舟编译器是首个取代Android虚拟机模式的静态编译器,可供开发者在开发环境中一次性将高级语言编译为机器码.此外,方舟编译器未来将支持多语言统一编译,可大幅提高开发效率. 编译器下载 [Ark] ...
- 机甲大师S1机器人编程学习
机甲大师 S1(RoboMaster S1)是大疆新出的教育机器人,很期待.S1支持Scratch和Python编程.(Scratch是麻省理工学院的“终身幼儿园团队”(Lifelong Kinder ...
- Laravel API跨域访问的实现步骤
本篇文章给大家带来的内容是关于Laravel API跨域访问的实现步骤,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 服务器A请求服务器B的接口,那么一般会出现跨域问题. 1 XML ...