进程间通信之管道

来源:互联网 发布:上古卷轴捏脸数据导入 编辑:程序博客网 时间:2024/05/16 03:54

1,管道

/*父子进程间的管道通信*/  2 #include<unistd.h>  3 #include<stdio.h>  4 #include<string.h>  5 #define MAXSIZE 100  6 int main(void)  7 {  8         int fd[2],pid,line;  9         char message[MAXSIZE]; 10  11 printf("current pid  = %ld \n",(long)getpid()); 12 printf("current ppid  = %ld \n",(long)getppid()); 13 printf("_________________________________\n"); 14         /*create pipe*/ 15         if(pipe(fd)==-1) 16         { 17                 perror("create pipe failed!"); 18                 return 1; 19         } 20         /*create new process*/ 21         else if((pid=fork())<0) 22         { 23                 perror("not create a new process!"); 24                 return 1; 25         } 26         /*child process*/ 27         else if(pid==0) 28         { 29                 close(fd[0]); 30                 printf("child process send message!\n"); 31                 write(fd[1],"Welcome to mrsoft!",19); 32   printf("current pid  = %ld \n",(long)getpid()); 33   printf("current ppid  = %ld \n",(long)getppid()); 34         } 35         else 36         { 37                 close(fd[1]); 38                 printf("parent process receive message is:\n "); 39                 line=read(fd[0],message,MAXSIZE); 40                 write(STDOUT_FILENO,message,line);                      //没有这一句,则无法打印 41                 printf("\n"); 42   printf("current pid  = %ld \n",(long)getpid()); 43   printf("current ppid  = %ld \n",(long)getppid()); 44                 <span style="color:#ff0000;">wait(NULL);</span> 45                 _exit(0); 46  47         }
 48         return 0; 49  50 }
输出:

mike@ubuntu:/home/test00$ ./pipe
current pid  = 9038 
current ppid  = 5789 
_________________________________
parent process receive message is:
child process send message!
Welcome to mrsoft! 
current pid  = 9038 
current ppid  = 5789 
current pid  = 9039 
current ppid  = 9038 
为什么父进程ID会不一样,我不理解???

fork()中父子进程数据独立,父子进程执行顺序不确定

vfork()中父子进程数据共享,子进程先执行,父进程后执行

2,命名管道

当打开FIFO时,非阻塞标志O_NONBLOCK将对以后读写产生如下影响:

1,没有使用O_NONBLOCK:访问无法满足要求时进程将阻塞。如试图读取空的FIFO,将导致进程阻塞。

2,使用O_NONBLOCK:访问无法满足要求时不阻塞,立刻返回错误,errno是ENXIO。

wait() and waitpid()
       The  wait() system call suspends execution of the calling process until
       one of its children terminates.  The call wait(&status)  is  equivalent
       to:
           waitpid(-1, &status, 0);
       The  waitpid()  system  call  suspends execution of the calling process
       until a child specified by pid argument has changed state.  By default,
       waitpid() waits only for terminated children, but this behavior is mod‐
       ifiable via the options argument, as described below.
       The value of pid can be:
       < -1   meaning wait for any child process whose  process  group  ID  is
              equal to the absolute value of pid.
       -1     meaning wait for any child process.
       0      meaning  wait  for  any  child process whose process group ID is
              equal to that of the calling process.

       > 0    meaning wait for the child whose process  ID  is  equal  to  the
              value of pid.

       The  value  of  options  is an OR of zero or more of the following con‐
       stants:
       WNOHANG     return immediately if no child has exited.
       WUNTRACED   also return if a child has  stopped  (but  not  traced  via
                   ptrace(2)).   Status for traced children which have stopped
                   is provided even if this option is not specified.
       WCONTINUED (since Linux 2.6.10)
                   also return if a stopped child has been resumed by delivery
                   of SIGCONT.

#include <unistd.h>#include <sys/types.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>int main(){int pipe_fd[2];pid_t pid;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;}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 success!\n");if(write(pipe_fd[1]," Pipe",5)!=-1)printf("parent write2 success!\n");close(pipe_fd[1]);sleep(3);<span style="color:#ff0000;">waitpid(pid,NULL,0);</span>//等待子进程结束exit(0);}return 0;}
pipe_read.c

#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define FIFO "/tmp/myfifo"main(int argc,char** argv){char buf_r[100];int  fd;int  nread;if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))printf("cannot create fifoserver\n");printf("Preparing for reading bytes...\n");memset(buf_r,0,sizeof(buf_r));fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);//open()等语句需在root下运行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 data yet\n");}printf("read %s from FIFO\n",buf_r);sleep(1);}pause();//等待暂停信号,例如kill()unlink(FIFO); //删除文件}
pipe_write.c

#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define FIFO_SERVER "/tmp/myfifo"main(int argc,char** argv){int fd;char w_buf[100];int nwrite;if(fd==-1)if(errno==ENXIO)printf("open error; no reading process\n");fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);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);}














0 0