1. Unknown MPs queue
Code:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <math.h> 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
Running result:
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
Conclusion: Because the fork function allows the child process to completely copy the entire address space of the parent process, the Parent and Child processes have both the read and write ends of the pipeline. What we need is a process read and a process write. Therefore, it is recommended that the write process close the read end and the read process close the write end.
2. Famous Pipelines
Code 1:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <math.h>#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;}
Code 2:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <math.h>#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
Running result:
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
Conclusion: first create a famous Pipeline, open the pipeline, write the string passed in by the main function to the pipeline, and then another process cyclically reads data from the pipeline. When there is no data, it cannot be read. When there is data, it can be read.
3. Signal Processing
Code:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <math.h>#include <signal.h> 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
Running result:
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
Conclusion: The signal system registers a signal processing function for the sigbus signal and then suspends the process to wait for the sigbus signal. The signal processing function is executed only when the sigbus signal is sent to the process.
4. Shared Memory
Code 1:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ipc.h>#include <sys/shm.h>#include <unistd.h>#include <errno.h>#include <math.h>#include <signal.h>#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;}
Code 2:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ipc.h>#include <sys/shm.h>#include <unistd.h>#include <errno.h>#include <math.h>#include <signal.h>#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;}
Code 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
Running result:
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
Conclusion: The two processes used for communication must communicate with the same shared memory. Therefore, the first parameter key of shmget must be the same.
5. Message Queue
Code 1:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <math.h>#include <signal.h>#include <sys/ipc.h>#include <sys/msg.h> 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;}
Code 2:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <math.h>#include <signal.h>#include <sys/ipc.h>#include <sys/msg.h> 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
Running result:
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
Conclusion: When msg2 is not running to add a message to the message queue, msg1 will be blocked on the msgrcv function. After msg2 is run, msg1 reads one message for each added message, until the added message is "end" and ends.