博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
和菜鸟一起深入学习国嵌实验之进程间通信
阅读量:4575 次
发布时间:2019-06-08

本文共 12460 字,大约阅读时间需要 41 分钟。

1、 无名管道

代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]){ pid_t pid; int pipe_fd[2]; char buf_r[100]; char *p_wbuf; int r_num; memset(buf_r, 0, sizeof(buf_r)); if(pipe(pipe_fd) < 0) { printf("pipe create error\n"); return -1; } //create child process if((pid = fork()) == 0) { printf("\n"); close(pipe_fd[1]); sleep(2); if((r_num = read(pipe_fd[0], buf_r, 100)) > 0) printf("%d numbers read from the pipe is %s\n", r_num, buf_r); close(pipe_fd[0]); exit(0); } else if(pid > 0) { close(pipe_fd[0]); if(write(pipe_fd[1], "Hello", 5) != -1) printf("parent write1 Hello\n"); if(write(pipe_fd[1], "Pipe", 5) != -1) printf("parent write2 Pipe\n"); close(pipe_fd[1]); waitpid(pid, NULL, 0); exit(0); } return 0;}

Makefile:

CC = gcc CURTDIR = $(shell pwd)TARGET = mypipe %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ clean:       rm-rf $(TARGET) $(TARGET).o

运行结果:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.1$makegcc -c mypipe.c -o mypipe.ogcc -o mypipe mypipe.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.1$lsMakefile mypipe  mypipe.c  mypipe.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.1$./mypipeparent write1 Helloparent write2 Pipe 10 numbers read from the pipe is HelloPipe

结论:由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。而我们需要的是一个进程读,一个进程写,所以写的进程最好关闭读端,读的进程关闭写端。

 

2、 有名管道

代码1:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#define FIFO_SERVER "/tmp/myfifo" int main(int argc, char *argv[]){ int fd; char w_buf[100]; int nwrite; if((mkfifo(FIFO_SERVER, O_CREAT | O_EXCL | O_RDWR) < 0) && (errno!= EEXIST)) printf("cannot create fifoserver\n"); fd = open(FIFO_SERVER, O_RDWR | O_NONBLOCK, 0); if(fd == -1) { perror("open"); exit(1); } if(argc == 1) { printf("please send something\n"); exit(-1); } strcpy(w_buf, argv[1]); if((nwrite == write(fd, w_buf, 100)) == -1) { if(errno == EAGAIN) printf("The FIFO has not been read yet. please try later\n"); } else printf("write %s to the FIFO\n", w_buf); close(fd); return 0;}

代码2:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#define FIFO_SERVER "/tmp/myfifo" int main(int argc, char *argv[]){ int fd; char buf_r[100]; int nread; if((mkfifo(FIFO_SERVER, O_CREAT | O_EXCL | O_RDWR) < 0) && (errno!= EEXIST)) printf("cannot create fifoserver\n"); fd = open(FIFO_SERVER, O_RDWR | O_NONBLOCK, 0); if(fd == -1) { perror("open"); exit(1); } while(1) { memset(buf_r, 0, sizeof(buf_r)); if(nread = read(fd, buf_r, 100) == -1) { if(errno == EAGAIN) printf("no datayet\n"); } printf("read %s from FIFO\n", buf_r); sleep(1); } close(fd); pause(); unlink(FIFO_SERVER); return 0;}

Makefile:

CC = gcc CURTDIR = $(shell pwd)TARGET = myfifo_write#TARGET = myfifo_read %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ clean:       rm-rf $(TARGET) $(TARGET).o       rm-rf $(TARGETR) $(TARGETR).o

运行结果:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.2$sudo ./myfifo_write hellowrite hello to the FIFOeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.2$sudo ./myfifo_write fifowrite fifo to the FIFO eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.2$sudo ./myfifo_readno data yetread from FIFOno data yetread from FIFOno data yetread from FIFOread hello from FIFOno data yetread from FIFOread fifo from FIFOno data yetread from FIFO

总结:先创建一个有名管道,打开管道之后向管道中写入由主函数传入的字符串,然后另一个进程循环从管道中读取数据。当没有数据时,是读不到的,当有数据时,就可以读到了。

 

3、 信号处理

代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
void my_func(int sign_no){ if(sign_no == SIGBUS) { printf("I have get SIGBUS\n"); }} int main(int argc, char *argv[]){ printf("Waiting for signal SIGBUS\n"); signal(SIGBUS, my_func); pause(); return 0;}

Makefile:

CC = gcc CURTDIR = $(shell pwd)TARGET = mysig %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ clean:       rm-rf $(TARGET) $(TARGET).o

运行结果:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$makegcc -c mysig.c -o mysig.ogcc -o mysig mysig.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$lsMakefile mysig  mysig.c  mysig.o  eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$./mysigWaiting for signal SIGBUS
eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$ps -aux | grep mysigWarning: bad ps syntax, perhaps a bogus'-'? See http://procps.sf.net/faq.htmleastmoon 10270  0.0 0.4   9116  3124 pts/2   S+   15:09   0:00 vi mysig.txteastmoon 10295  0.0 0.0   1728   244 pts/3   S+   15:10   0:00 ./mysigeastmoon 10300  0.0 0.1   5804   876 pts/4   S+   15:11   0:00 grep --color=auto mysigeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$kill -BUS 10295  eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$./mysigWaiting for signal SIGBUSI have get SIGBUS

总结:signal系统调用为SIGBUS信号注册了信号处理函数,然后将进程挂起等待SIGBUS信号,当向该进程发送SIGBUS信号才会执行信号处理函数。

 

4、 共享内存

代码1:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "shm_com.h" int main(int argc, char *argv[]){ int running = 1; void *shared_memory = (void*)0; struct shared_use_st *shared_stuff; int shmid; shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT); if(shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); } shared_memory = shmat(shmid, (void*)0, 0); if(shared_memory == (void*)-1) { fprintf(stderr, "shmmat failed\n"); exit(EXIT_FAILURE); } printf("Memory attached at %x\n", (int)shared_memory); shared_stuff = (struct shared_use_st *)shared_memory; shared_stuff->written_by_you = 0; while(running) { if(shared_stuff->written_by_you) { printf("You wrote: %s\n", shared_stuff->some_text); sleep(1); shared_stuff->written_by_you = 0; if(strncmp(shared_stuff->some_text, "end", 3) == 0) { running = 0; } } } if(shmdt(shared_memory) == -1) { fprintf(stderr, "shmmdt failed\n"); exit(EXIT_FAILURE); } return 0;}

代码2:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "shm_com.h" int main(int argc, char *argv[]){ int running = 1; void *shared_memory = (void*)0; struct shared_use_st *shared_stuff; char buffer[BUFSIZ]; int shmid; shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT); if(shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); } shared_memory = shmat(shmid, (void*)0, 0); if(shared_memory == (void*)-1) { fprintf(stderr, "shmmat failed\n"); exit(EXIT_FAILURE); } printf("Memory attached at %x\n", (int)shared_memory); shared_stuff = (struct shared_use_st *)shared_memory; shared_stuff->written_by_you = 0; while(running) { while(shared_stuff->written_by_you) { sleep(1); printf("Waiting for client....\n"); } printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); strncpy(shared_stuff->some_text, buffer, TEXT_SZ); shared_stuff->written_by_you = 1; if(strncmp(buffer, "end", 3) == 0) { running = 0; } } if(shmdt(shared_memory) == -1) { fprintf(stderr, "shmmdt failed\n"); exit(EXIT_FAILURE); } return 0;}

代码3:

#define TEXT_SZ 2048 struct shared_use_st{   int written_by_you;   char some_text[TEXT_SZ];};

Makefile:

CC = gcc CURTDIR = $(shell pwd)#TARGET = myshm1TARGET = myshm2 %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ clean:       rm-rf $(TARGET) $(TARGET).o

运行结果:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$makegcc -c myshm1.c -o myshm1.ogcc -o myshm1 myshm1.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$lsMakefile myshm1  myshm1.c  myshm1.o myshm2.c  shm_com.h eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$makegcc -c myshm2.c -o myshm2.ogcc -o myshm2 myshm2.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$lsMakefile myshm1  myshm1.c  myshm1.o myshm2  myshm2.c  myshm2.o shm_com.h eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$./myshm1Memory attached at b78db000 eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$./myshm2Memory attached at b7731000Enter some text: my first share memoryWaiting for client....Waiting for client....Enter some text: it's so goodWaiting for client....Waiting for client....Enter some text: ok, now let's study otherthings.                                            Waiting for client....Waiting for client....Enter some text: end     eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$./myshm1Memory attached at b78db000You wrote: my first share memory You wrote: it's so good You wrote: ok, now let's study otherthings. You wrote: end

总结:用于通信的两个进程必须用同一块共享内存进行通信,所以shmget的第一个参数key必须是相同的。

 

 

5、 消息队列

代码1:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct my_msg_st{ long int my_msg_type; char some_text[BUFSIZ];}; int main(int argc, char *argv[]){ int running = 1; int msgid; struct my_msg_st some_data; long int msg_to_receive = 0; msgid = msgget((key_t)2222, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } while(running) { if(msgrcv(msgid, (void*)&some_data, BUFSIZ, msg_to_receive, 0) ==-1) { fprintf(stderr, "msgrcv failed with error: %d\n", errno); exit(EXIT_FAILURE); } printf("You wrote: %s\n", some_data.some_text); if(strncmp(some_data.some_text, "end", 3) == 0) { running = 0; } } if(msgctl(msgid, IPC_RMID, 0) == -1) { fprintf(stderr, "msgctl failed with error: %d\n", errno); exit(EXIT_FAILURE); } return 0;}

代码2:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct my_msg_st{ long int my_msg_type; char some_text[BUFSIZ];}; int main(int argc, char *argv[]){ int running = 1; int msgid; struct my_msg_st some_data; char buffer[BUFSIZ]; msgid= msgget((key_t)2222, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } while(running) { printf("Enter some text:"); fgets(buffer, BUFSIZ, stdin); some_data.my_msg_type = 1; strcpy(some_data.some_text, buffer); if(msgsnd(msgid, (void*)&some_data, BUFSIZ, 0) == -1) { fprintf(stderr, "msgsnd failed with error: %d\n", errno); exit(EXIT_FAILURE); } if(strncmp(some_data.some_text, "end", 3) == 0) { running = 0; } } return 0;}

Makefile:

CC = gcc CURTDIR = $(shell pwd)TARGET = mymsg1#TARGET = mymsg2 %.o:%.c       $(CC)-c $(EXTRAFLAGS) $< -o $@%.o:%.S       $(CC)-c $(EXTRAFLAGS) $< -o $@ .PHONY: all clean $(TARGET): $(TARGET).o       $(CC)  -o $@ $^ clean:       rm-rf $(TARGET) $(TARGET).o

运行结果:

eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$makegcc -c mymsg1.c -o mymsg1.ogcc -o mymsg1 mymsg1.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$lsMakefile mymsg1  mymsg1.c  mymsg1.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$makegcc -c mymsg2.c -o mymsg2.ogcc -o mymsg2 mymsg2.o eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$lsMakefile mymsg1  mymsg1.c  mymsg1.o mymsg2  mymsg2.c  mymsg2.o  eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$./mymsg2Enter some text:helloEnter some text:mymsgEnter some text:good-buy   Enter some text:end  eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$./mymsg1You wrote: hello You wrote: mymsg You wrote: good-buy You wrote: end

总结:在没有运行msg2向消息队列中添加消息的时候,msg1会阻塞在msgrcv函数上,运行msg2后,每添加一条消息,msg1就读取一条,直到添加的消息为”end”,结束。

转载于:https://www.cnblogs.com/wuyida/archive/2013/02/03/6300020.html

你可能感兴趣的文章
js实现动态添加删除(留言板)
查看>>
如何实现一个高效的单向链表逆序输出?
查看>>
JavaScript中严格判断NaN
查看>>
json_encode不自动转义斜杠“/”的方法
查看>>
【转贴】SQL2005的系统表
查看>>
CentOS 7安装PHP依赖管理Composer以及指定PHP版本使用Composer
查看>>
循序渐进大型网站架构
查看>>
Thinkphp5.0支付宝支付扩展库类库大全
查看>>
Nodejs+Express 搭建 web应用
查看>>
2013春节出游兴“专机游”
查看>>
Leetcode 67. Add Binary
查看>>
表达式
查看>>
mysql 创建用户名及密码
查看>>
VMware虚拟机安装Centos7后设置静态ip
查看>>
关于windows nginx不能启动问题的解决,史上最坑系列之一(原文)
查看>>
ssh免密码登录与常见问题
查看>>
区块链学习一
查看>>
五 搭建kafka集群
查看>>
Linux 内核即插即用规范
查看>>
Ping- Ip- Linux必学的60个命令
查看>>