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”,结束。