实验三: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 ...
随机推荐
- github 白嫖记(一)
位运算 按位操作符:0或者1之间的运算 a|b 或 任意一个为1结果为1 console.log(0 | 1) //1 console.log(1 | 0) //1 console.log(1 | 1 ...
- HttpRuntime.Cache 与 HttpContext.Current.Cache
1.HttpRuntime.Cache是应用程序级别的, 2.而HttpContext.Current.Cache是针对当前WEB上下文定义的. 3.这二个都是调用的同一个对象,不同的是:HttpRu ...
- Java se课程设计详解——数据库接口类(1)
开始做课程设计的时候根本无从下手,后来查阅资料后发现是先从数据库开始的.整个课程设计需要用到的如下图,今天总结一下数据库接口! 数据库接口需要用到两个类,一个是DAO.java,另一个是propert ...
- WPF 精修篇 管理资源字典
原文:WPF 精修篇 管理资源字典 样式太多 每个界面可能需要全局的样式 有没有肯能 WPF 中的样式 像Asp.net中 的CSS一样管理那 有的 有资源字典 BurshDictionary &l ...
- 一般处理程序Session
1.要在一般处理程序中获取其他页面的session值,需要引用名空间: using System.Web.SessionState; 2.然后继承一个接口:IRequiresSessionState ...
- webapi行程开发文档
1.新建webapi项目 2.项目中controllers 中有一个values的为webapi接口 3.areas中域中有helppage为生成文档可以直接运行localhost/help,就会生成 ...
- eclipse 标记任务
eclipse 标记任务 eclipse Task Tags: TODO -用来提醒该标识处的代码有待返回继续编写.更新或者添加.该标签通常在注释块的源文件顶部. FIXME -该标签用来提醒你代码中 ...
- python高级编程——网络编程(三)
TCP和并发服务器 与UDP不同的是,他是一个面向连接的,可靠的数据传输协议 TCP通信比较复杂 先写一个TCP服务器,一般步骤如下: 1.首先是要创建一个socket套接字:socket() 2.服 ...
- 英语chrysopal金绿宝石chrysopal单词
chrysopal金绿宝石,也称金绿玉.化学成分为BeAl2O4.晶体属正交(斜方)晶系的氧化物矿物.它位列名贵宝石,具有四个变种:猫眼,变石,变石猫眼和金绿宝石晶体. 金绿宝石本身就是较稀少的矿物, ...
- Linux shell 中断循环语句
无限循环: 循环有限的生命,他们跳出来,一旦条件是 false 还是 false 取决于循环. 由于所需的条件是不符合一个循环可能永远持续下去.永远不会终止执行一个循环执行无限次数.出于这个原因,这样 ...