Linux应用编程-进程通信

通信方式有管道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);
	}
}




二、信号

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值