实验三: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 ...
随机推荐
- 【MySQL】Mariadb字符集
Mariadb字符集 如果不设置字符集,可以查看mariadb的字符集的默认设置是latin1. 如下命令,查看Mariadb的默认配置: [root@oradb ~]# /usr/local/mys ...
- Navicat MYSQL 建立关联表 保存时遇到 cannot add foreign key constraint
首先建立user表,如下图 然后建立message表,userid用作外键,关联user表的id 点击上面的外键按钮,添加外键如下 结果保存时报错: cannot add foreign key co ...
- R数据挖掘 第三篇:聚类的评估(簇数确定和轮廓系数)和可视化
在实际的聚类应用中,通常使用k-均值和k-中心化算法来进行聚类分析,这两种算法都需要输入簇数,为了保证聚类的质量,应该首先确定最佳的簇数,并使用轮廓系数来评估聚类的结果. 一,k-均值法确定最佳的簇数 ...
- 《跟唐老师学习云网络》 -第4篇 router路咋走啊【华为云技术分享】
[摘要] 好了,到这里至少你应该能看懂路由表信息了.给你一个目的IP,你也应该知道它会使用哪一条路由了. 路怎么走就看骚年你了~ 一.路由 其实关于网络大家遇到最多的问题就是:卧 槽,为什么不通啊! ...
- excel中统计列中的值在其他列出现的次数多个条件
excel中统计列中的值在其他列出现的次数多个条件 =COUNTIFS(E2:E373,"=VIP经销商",J2:J373,K2) 解释 E列的第二行到第373行中值 等于 VIP ...
- 单片机成长之路(51基础篇) - 023 N76e003 系统时钟切换到外部时钟
N76e003切换到外部时钟的资料很少(因为N76e003的片子是不支持无源晶振的,有源晶振的成本又很高,所以网上很少有对N76e003的介绍).有图有真相: 代码如下: main.c #includ ...
- spring好文章整理
彻底搞明白Spring中的自动装配和Autowired IDEA编译spring 5源码 Spring源码——IDEA读Spring源码环境搭建 导入spring源码org.springframewo ...
- 2019-11-29-WPF-高速书写-StylusPlugIn-原理
原文:2019-11-29-WPF-高速书写-StylusPlugIn-原理 title author date CreateTime categories WPF 高速书写 StylusPlugIn ...
- QQ互联,填写回调时注意事项
今天在做QQ登录接口的时候,填写回调地址的时候,竟然出现了诡异的事情. 我的回调地址我直接填的域名,也申请通过了.但是在做开发地时候,一直提示这蛋疼的 redirect uri is illegal ...
- Fundebug录屏插件更新至0.4.0,修复BUG,优化性能
摘要: 录屏功能更加强大,欢迎免费试用! 关于Fundebug录屏功能 Fundebug是专业的程序BUG监控服务,当线上应用出现BUG的时候,我们可以第一时间报警,帮助开发者及时发现BUG,提高De ...