什么是进程
进程是linux中独立分配资源的最小单位,具有独立的内存空间和堆栈。进程因异常退出后,也不会影响其他进程的运行。
无名管道
特点:
- 一种半双工的通信方式,数据只能单向流动
- 只能在具有亲缘进程间使用。父子进程
- 是一种特殊的文件,可以使用read, write等函数,。不属于文件系统,只存在进程的内存中。
重要函数:
filedes[o] 用于读取,filedes[1]用于写入
#include <unistd.h>
int pipe(int filedes[2]);
代码示例:
用管道文件,创建由父进程到子进程的管道,父进程循环输入数据,子进程循环读取数据,当写端输入end时,父子线程都结束。
子进程是父进程的复制品
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
int main()
{
int fd[2];
pipe(fd);
pid_t pid = fork();
if(pid == 0) {
close(fd[1]);
char buff[128] = {0};
int n = 0;
while((n = read(fd[0],buff,127)) > 0){
printf("child read:%s\n",buff);
}
close(fd[0]);
} else{
close(fd[0]);
while(1){
char buff[128] = {0};
printf("input:\n");
fgets(buff,128,stdin);
if(strncmp(buff,"end",3)==0) {
break;
}
write(fd[1],buff,127);
}
close(fd[1]);
}
exit(0);
}
有名管道
特点:
- 半双工的通信方式,数据只能单向流动
- 只要打开相同管道文件,任何两个进程都可以通信
- 有名管道也叫命名管道,在文件系统目录中存在一个管道文件。管道文件仅仅是文件系统中的标示,并不在磁盘上占据空间。在使用时,在内存上开辟空间,作为两个进程数据交互的通道。
管道创建:
- 方式1
在shell中使用mkfifo 命令
mkfifo filename
- 方式 2
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);
使用方法:
- open函数打开管道文件
如果一个进程以只读方式打开,那么它会被阻塞到open,直到另一个进程以只写或读写。 - 可以使用read, write, close函数读写关闭管道,
示例:
一个进程写,一个进程读。
写端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
//信号处理函数。
void fun(int sig)
{
printf("sig == %d\n",sig);
}
int main()
{
signal(SIGPIPE,fun);
int fd = open("fifo",O_WRONLY);
// int fd = open("fifo",O_RDWR);
assert(fd != -1);
printf("fd = %d\n",fd);
char buff[128] = {0};
while(1)
{
printf("input:\n");
fgets(buff,128,stdin);
write(fd,buff,strlen(buff));
if(strncmp(buff,"end",3)==0)
{
break;
}
}
close(fd);
exit(0);
}
读端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
int main()
{
int fd = open("fifo",O_RDONLY);
assert(fd != -1);
printf("fd = %d\n",fd);
char buff[128] = {0};
// while(1)
// {
// int n = read(fd,buff,127);//127是期望要读的字符个数
// if(strncmp(buff,"end",3)==0)
// {
// break;
// }
// printf("read:%s\n",buff);
// printf("n = %d\n",n);
// }
int n = 0;
while((n = read(fd,buff,127))>0)
{
printf("read:(n = %d)%s\n",n,buff);
//将buff中的数据清空
memset(buff,0,128);
}
close(fd);
exit(0);
}
总结:
- 两个进程通信时,写端打开时,读端才会读取到数据,或被read阻塞
- 两个进程通信时,写端关闭时,读端read返回0,然后关闭
- FIFO管道严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。
4asxsda
相同点
- 打开管道文件以后,在内存中开辟了一块空间,管道的内容在内存中存放,有两个指针—-头指针(指向写的位置)和尾指针(指向读的位置)指向它。读写数据都是在给内存的操作,并且都是半双工通讯。
区别
- 有名在任意进程之间使用,无名在父子进程之间使用。
820

被折叠的 条评论
为什么被折叠?



