通信方式有管道pipe,信号
一、pipe
管道分两种无名管道,有名管道。
1、无名管道:
父进程和子进程可通过无名管道传输数据,管道有两个口,一端写一端读,半双工通信。可以当作文件进行操作,所以创建的管道会有两个文件描述符fds[0]和fds[1],fds[0]用于读,fds[1]用于写,关系如图。
实验:创建管道,再创建子进程,父进程将信息发送到子进程。
#include<stdio.h>
#include<sys/types.h> /* 定义数据类型,如 ssize_t,off_t 等 */
#include <fcntl.h> /* 定义 open,creat 等函数原型,创建文件权限的符号常量 S_IRUSR 等 */
#include <unistd.h> /* 定义 read,write,close,lseek 等函数原型 */
#include <errno.h> /* 与全局变量 errno 相关的定义 */
#include <sys/ioctl.h> /* 定义 ioctl 函数原型 */
#include <stdlib.h>
int main(int argc, char *argv[]) {
pid_t pid,wait_pid = -1;
int *sub_process_status;
int pipefd[2] = {0};
char buf[10] = {0};
buf[9] = '\0';
if(pipe(pipefd) < 0) /*创建管道*/
{
printf("pipe error");
exit(5);
}
pid = fork(); /* 创建进程 */
if (pid == 0) /* 对子进程返回 0 */
{
printf("Here is child, my pid = %d, parent's pid = %d\n", getpid(), getppid()); /* 打印父子进程 PID */
close(pipefd[1]); /*在子进程关闭写端*/
while(1)
{
if(read(pipefd[0],buf,sizeof(buf)) > 0)
{
printf("child get word is %s\n",buf);
break;
close(pipefd[0]);
}
}
exit(7);
} else
if(pid > 0) /*对父进程返回子进程 PID */
{
close(pipefd[0]); /*在父进程关闭读端*/
printf("Here is parent, my pid = %d, child's pid = %d\n", getpid(), pid);
scanf("%s",buf);
write(pipefd[1],buf,sizeof(buf));
close(pipefd[1]);
wait_pid = wait(NULL);
printf("child exit\n");
printf("child return status value is %d\n",*sub_process_status);
printf("wait_pid is %d\n",wait_pid);
}
else
{ /* fork 出错 */
perror("fork error\n");
}
return 6;
}
输入:
happy
输出:
Here is parent, my pid = 6164, child's pid = 6165
Here is child, my pid = 6165, parent's pid = 6164
happy
child get word is happy
child exit
child return status value is 29590344
wait_pid is 6165
2、有名管道
它可以使互不相关的两个进程实现彼此的通信。它提供了一个路径与其关联,以文件形式存在于文件系统中 。在建立有名管道后,就可以把它当作普通文件来进行读写操作 。
创建有名管道的创建使用函数 mkfifo()
所需头文件 | #include <sys/types.h> #include <sys/state.h> |
函数原型 | int mkfifo(const char *filename, mode_t mode) |
函数传入值 | filename:要创建的管道 mode: O_RDONLY:读管道 O_WRONLY:写管道 O_RDWR:读写管道 O_NONBLOCK:非阻塞 O_CREAT:如果该文件不存在,那么就创建一个新的文件,并 用 第三的参数为其设置权限 O_EXCL:如果使用 O_CREAT 时文件存在,那么可返回错误消 息。 这一参数可测试文件是否存在 |
函数返回值 | 成功:0 出错:-1 |
实验:创建两个应用,一个读一个写,读程序负责创建管道,将读到的数据打印。
//读端
#include<stdio.h>
#include<sys/types.h> /* 定义数据类型,如 ssize_t,off_t 等 */
#include <fcntl.h> /* 定义 open,creat 等函数原型,创建文件权限的符号常量 S_IRUSR 等 */
#include <unistd.h> /* 定义 read,write,close,lseek 等函数原型 */
#include <errno.h> /* 与全局变量 errno 相关的定义 */
#include <sys/ioctl.h> /* 定义 ioctl 函数原型 */
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"
main(int argc,char** argv)
{
char buf[100];
int fd;
int nread;
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0))
printf("pipe creat fail\n");
memset(buf,0,sizeof(buf));
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
while(1)
{
memset(buf,0,sizeof(buf));
if((nread=read(fd,buf,100))==-1){
if(errno==EAGAIN)
printf("no data yet\n");
}
printf("read %s from FIFO\n",buf);
sleep(1);
}
pause();
unlink(FIFO);
}
//写端
/*fifo_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 buf[100];
int nwrite;
if(fd==-1)
printf("open error; no readingprocess\n");
fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
if(argc==1)
printf("Please send something\n");
else
{
strcpy(buf,argv[1]);
if((nwrite=write(fd,buf,100))==-1)
{
if(errno==EAGAIN)
printf("The FIFO has not beenread yet.Please try later\n");
}
else
printf("write %s to theFIFO\n",buf);
}
}
二、信号