企业网站项目的流程,中国建筑人才网证书查询,海外推广软件,网站怎样秒收录文章目录 无名管道pipe有名管道 进程之间的通信#xff1a;Linux环境下#xff0c;进程地址空间相互独立#xff0c;每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到#xff0c;所以进程之间不能相互访问#xff0c;要交换数据必须通过… 文章目录 无名管道pipe有名管道 进程之间的通信Linux环境下进程地址空间相互独立每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到所以进程之间不能相互访问要交换数据必须通过内核。如图在内核中开辟一块缓冲区进程1把数据从用户空间拷贝到内核缓冲区进程2在从内核缓冲区中把数据读走内核提供的这种机制称为进程间通信IPCInterProcess Communication 管道是LInux/Unix最经典的一种通信方式管道实质上是父子进程借助内存文件的一种通信方式。借助进程映像加载等手段它可以实现两个程序之间的数据交换。管道的本质是一块内核缓冲区由两根文件描述符引用一个表示读端一个表示写端规定数据从管道的写端流入管道从读端流出。当两根进程都终结的时候管道会自动消失。默认的管道的读端和写端都是堵塞的。管道包括两种无名管道和有名管道。 无名管道pipe 使用无名管道时还可以搭配使用close()关闭文件描述符和dup()复制管道文件描述符来实现输入输出标准的重定向。 #includeunistd.h
#includestdlib.h
#includestdio.h
#includestring.hint main(){int data_processed;int file_pipes[2];const char some_data[]123;char buffer[BUFSIZ1];memset(buffer,\0,sizeof(buffer));if(pipe(file_pipes)0){data_processedwrite(file_pipes[1],some_data,strlen(some_data));printf(Wrote %d bytes\n,data_processed);data_processedread(file_pipes[0],buffer,BUFSIZ);printf(Read %d bytes:%s\n,data_processed,buffer);exit(EXIT_SUCCESS);}exit(EXIT_FAILURE);
}[cchaubin os]$ gcc demo.c
[cchaubin os]$ ./a.out
Wrote 3 bytes
Read 3 bytes:123
[cchaubin os]$ menset是c语言的初始化函数作用是将某一块内存中的内容全部设置为指定的值这个函数通常为新申请的内存做初始化工作。void *memset(void *s, int ch, size_t n);将s中当前位置后面的n个字节 typedef unsigned int size_t 用 ch 替换并返回 s 。int pipe(int fd[2])用于创建一个管道如果函数调用成功fd[0]存放管道的读端fd[1]存放管道的写端都是文件描述符并且返回0如果失败则返回-1并设置errno值。 当父进程使用pipe创建管道之后一般需要再fork一个子进程然后通过管道实现父子进程之间的通信。一般来说只要两个进程有血缘关系有共同的祖先就可以使用管道进行通信。 父进程创建管道 父进程fork子进程 父进程关闭读端子进程关闭写端实现进程之间通信 #includeunistd.h
#includestdlib.h
#includestdio.h
#includestring.hint main(){int data_processed;int file_pipes[2];const char some_data[]123;char buffer[BUFSIZ1];pid_t fork_result;memset(buffer,\0,sizeof(buffer));if(pipe(file_pipes)0){fork_resultfork();if(fork_result-1){fprintf(stderr,Fork failure);exit(EXIT_FAILURE);}//子进程if(fork_result0){data_processedread(file_pipes[0],buffer,BUFSIZ);printf(son:Read %d bytes:%s\n,data_processed,buffer);exit(EXIT_SUCCESS);}else{data_processedwrite(file_pipes[1],some_data,strlen(some_data));printf(father:Wrote %d bytes\n,data_processed);}exit(EXIT_SUCCESS);}exit(EXIT_FAILURE);
}[cchaubin os]$ gcc demo.c
[cchaubin os]$ ./a.out
father:Wrote 3 bytes
son:Read 3 bytes:123
[cchaubin os]$ 管道实现程序之间的通信 //pipe4.c
#includeunistd.h
#includestdlib.h
#includestdio.h
#includestring.hint main(int argc,char *argv[]){int data_processed;char buffer[BUFSIZ1];int file_descriptor;memset(buffer,\0,sizeof(buffer));sscanf(argv[1],%d,file_descriptor);//读取格式化的argv[1]给file_descriptordata_processedread(file_descriptor,buffer,BUFSIZ);printf(%d-read %d bytes:%s\n,getpid(),data_processed,buffer);exit(EXIT_FAILURE);}# 0表示键盘从键盘中读取输入并且输出
[cchaubin os]$gcc pipe4.c -o pipe
[cchaubin os]$ ./pipe 0
123466
4947-read 7 bytes:123466[cchaubin os]$ #includeunistd.h
#includestdlib.h
#includestdio.h
#includestring.hint main(){int data_processed;int file_pipes[2];const char some_data[]123;char buffer[BUFSIZ1];pid_t fork_result;memset(buffer,\0,sizeof(buffer));if(pipe(file_pipes)0){fork_resultfork();if(fork_result-1){fprintf(stderr,Fork failure);exit(EXIT_FAILURE);}//子进程if(fork_result0){sprintf(buffer,%d,file_pipes[0]);//将file_pipes[0]转换成字符串以适应execl调用中参数类型的要求其中fotmat参数与print中的类型一致/*execlp(ls, ls, -l, -F, NULL); 使用程序名在PATH中搜索。execl(/bin/ls, ls, -l, -F, NULL); 使用参数1给出的绝对路径搜索。*/if(execl(pipe,pipe,buffer,(char *)0)-1)printf(execl error\n);exit(EXIT_FAILURE);}else{data_processedwrite(file_pipes[1],some_data,strlen(some_data));printf(father:Wrote %d bytes\n,data_processed);}exit(EXIT_SUCCESS);}exit(EXIT_FAILURE);
}[cchaubin os]$ gcc demo.c
[cchaubin os]$ ./a.out
father:Wrote 3 bytes
argv[1]3
6098-read 3 bytes:123
[cchaubin os]$ 有名管道 有名管道可以实现两个没有血缘关系的进程进行通信。 [cchaubin s]$ mkfifo pp
[cchaubin s]$ ls -la
总用量 44
drwxrwxr-x. 2 cch cch 80 11月 7 11:01 .
drwxr-xr-x. 5 cch cch 72 10月 14 20:04 ..
-rwxrwxr-x. 1 cch cch 14176 10月 23 19:09 a.out
-rw-r--r--. 1 cch cch 12288 10月 14 17:17 .cc.c.swp
-rw-------. 1 cch cch 12288 10月 12 17:05 .file1.c.swp
-rw-rw-r--. 1 cch cch 206 11月 7 11:00 file.c
prw-rw-r--. 1 cch cch 0 11月 7 11:01 pp可以看到当使用mkfifo创建有名管道后管道文件的信息的第一个显示为p表示其为管道文件 [cchaubin s]$ echo hhhhsjiqqpp 在命令行内输入以上一开始管道会堵塞因为它会等待一个进程读取数据 [cchaubin s]$ cat pp
hhhhsjiqq
[cchaubin s]$