进程间通信方式:IPC(管道、共享内存、信号量) 、信号。
IPC:
信号:约定好了,什么信号干什么事。
----------------------------------------------------------------------------------------------------------------------------------------------------------------
管道分:
1.标准流管道
2.无名管道
3.命名管道(有名管道)
FILE* popen(const char* command, const char* open_mode);
popen允许一个程序将另一个程序作为新进程来启动。command字符串是要运行的程序名(即,被调用程序)。open_mode必须是“r”或“w”。调用popen函数,会做两件事:1.创建新的进程command。2.在程序和被调用程序之间建立一条标准流管道。
如果open_mode是“r”:则调用函数对管道就是读,被调用函数对管道就是写,并且把被调用函数的标准输出重定向到了写端。
如果open_mode是“w”:则调用函数对管道就是写、被调用函数对管道就是读,并且把被调用函数的标准输入重定向到了读端。
例1:
第一步:vim printf.c
int main(){
//输出到标准输出上。因为这里printf是popen新建的进程。而新创建的进程的标准输出重定向到了
写端。所以也就是往管道里输出了字符串。
}
第二步:gcc printf.c -o printf//这就是要执行的程序
int main(int argc,char *argv[]){
popen(argv[1],"r")//将argv[1]作为新的进程来启动。即,新建的进程为:printf。
//读管道的东西到buf中。新建的进程printf向标准输出写了"Hello world\n",而新建的进程的
标准输出重定向到了管道。所以读管道的内容就是"Hello world\n"。
//打印出读出的内容:Hello world
}
第四步:gcc popen_r.c -o popen_r
//将命令"./printf"作为参数传进去。
例2:
第一步:vim fgets.c
int main(){
}
第二步:gcc fgets.c fgets
第三步:vim popen_w.c
int main(int argc,char* argv[])
{
}
第四步:gcc popen_w.c -o popen_w
第五步:./popen_w ./fgets hello
2.无名管道
无名管道只能在亲缘关系进程间通信(父子或兄弟)。
int fds[2];pipe(fds);后内核里面只有一条管道,父进程和子进程同时各有了一个管道的读端和写端。但是:每个进程只能用其中的一个。要么:父进程从fd[1]写,子进程从fd[0]读。要么子进程从fd[1]写,父进程就从fd[0]读。
例:
int fds[2];
//新建了一条管道,并把读端和写端打开。
//子进程
close(fds[1])//fds[0]是读,fds[1]是写。子进程关闭写端。对于新创建的
//从读端读
close(fds[0])//关闭读端
close(fds[0])//父进程关闭读端。
//向写端写。
close(fds[1])//关闭写端
3.命名管道(有名管道):
有名管道的使用跟前面学习的管道文件一样,只不过是用函数创建的管道。
例:创建有名管道:
int main(){
mkfifo("1.fifo",0666);
}
文章来源: 进程间通信:IPC-管道