进程间通信 有名管道

本文介绍了如何在C语言中通过有名管道(命名管道)实现两个进程间的通信,包括mkfifo函数的使用、文件操作、进程创建与控制。通过Rose和Jake两个进程的交互,展示了数据的发送和接收,以及在接收到bye时的进程终止机制。
摘要由CSDN通过智能技术生成

 有名管道(有名管道也叫命名管道,在文件系统目录中存在一个管道文件)

头文件:#include <sys/types.h>
		#include <sys/stat.h>
函数原型:int mkfifo(const char *pathname, mode_t mode);
参数:pathname有名管道文件的路径+管道名  例如:/tmp/myfifo
     mode管道文件权限 0777满权限
     返回值:成功 0
             失败返回 -1

实现两个进程间的互相通信,一个进程可以和另一个进程互相沟通,并且当发送bye时,退出进程,并创建日志文件记录通信数据

jake.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <signal.h>
int main()
{
	//创建子进程
	pid_t pid=fork();
	if(pid==-1)
	{
		perror("pid");
	}
	else if(pid==0)
	{
		//子进程
		//jake 接收rose发送的数据
		//2.打开rose->jake的管道文件
		int rose_jake=open("/tmp/youfifo",O_RDWR);
		if(rose_jake==-1)
		{
			perror("open rose_jake");
		}
		//打开日志文件
		int fd_txt=open("./1.txt",O_RDWR|O_CREAT,0777);
		if(fd_txt==-1)
		{
			perror("fd_txt");
			return -1;
		}
		char jake_read[100]={0};//定义jake收到的数据
		while(1)
		{
			read(rose_jake,jake_read,sizeof(jake_read));//从管道文件中读取数据
			printf("%s\n",jake_read);//打印数据
			write(fd_txt,jake_read,strlen(jake_read));//将收到的数据写到日志文件中
			
			if(strstr(jake_read,"bye")!=NULL)//判断收到的字符串中有“bye”就结束进程
			{
				close(fd_txt);
				close(rose_jake);
				kill(getppid(),SIGKILL);
				kill(getpid(),SIGKILL);
				exit(0);
			}
			bzero(jake_read,100);//清空
		}
	}
	else if(pid>0)
	{
		//jake 发送消息
		//1.创建jake->rose管道文件
        int ret=mkfifo("/tmp/myfifo",0777);
        if(ret==-1)
        {
            perror("myfifo build error");
            return -1;
        }
		//2.打开jake->rose的管道文件
		int jake_rose=open("/tmp/myfifo",O_RDWR);
		if(jake_rose==-1)
		{
			perror("open jake_rose");
		}
		char buf_jake_write[500]={0};//定义数组写入发送的总数据
		time_t t;//定义时间变量
		char jake_write[100];//jake写的数据
		while(1)
		{
			time(&t);
			bzero(buf_jake_write,500);//清空
			bzero(jake_write,100);//清空
			fgets(jake_write,100,stdin);//写数据
			char jake[100]="from jake";
			snprintf(buf_jake_write,500,"[%s] %s:%s\n",ctime(&t),jake,jake_write);//拼接字符串
			write(jake_rose,buf_jake_write,strlen(buf_jake_write));//写入数据到管道文件中
			if(strstr(jake_write,"bye")!=NULL)//判断输入的字符串中有“bye”就结束进程 模糊匹配字符串
			{
				close(jake_rose);
				kill(pid,SIGKILL);
				kill(getpid(),SIGKILL);
				exit(0);
			}
		}
	}
}

rose.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
int main()
{
	//创建子线程
	//rose发送消息
	pid_t pid1=fork();
	if(pid1==-1)
	{
		perror("pid1");
	}
	else if(pid1==0)
	{
		//子进程
		//1.创建rose->jake管道文件
        int ret=mkfifo("/tmp/youfifo",0777);//管道文件创建再根目录下的tmp文件夹下
        if(ret==-1)
        {
            perror("myfifo build error");
            return -1;
        }
		//打开rose->jake的管道文件
		int rose_jake=open("/tmp/youfifo",O_RDWR);
		if(rose_jake==-1)
		{
			perror("open rose_jake");
		}
		char buf_rose_write[100]={0};//定义数组写入发送的总数据
		time_t t;//定义时间变量
		char rose_write[100];
		while(1)
		{
			time(&t);
			bzero(buf_rose_write,100);//清空
			bzero(rose_write,100);//清空
			fgets(rose_write,100,stdin);//写数据
			char rose[100]="from rose";
			snprintf(buf_rose_write,500,"[%s] %s:%s\n",ctime(&t),rose,rose_write);//拼接字符串
			write(rose_jake,buf_rose_write,strlen(buf_rose_write));//写入数据到管道文件中
			if(strstr(rose_write,"bye")!=NULL)//判断输入的字符串中有“bye”就结束进程 模糊匹配字符串
			{
				close(rose_jake);
				kill(getppid(),SIGKILL);
				kill(getpid(),SIGKILL);
				exit(0);
			}
		}
	}
	else if(pid1>0)
	{
		//打开jake->rose的管道文件
		int jake_rose=open("/tmp/myfifo",O_RDWR);
		if(jake_rose==-1)
		{
			perror("open jake_rose");
			return -2;
		}
		//打开日志文件
		int fd_txt=open("./1.txt",O_RDWR|O_CREAT,0777);
		if(fd_txt==-1)
		{
			perror("fd_txt");
			return -1;
		}
		char rose_read[500]={0};//定义rose收到的数据
		while(1)
		{
			read(jake_rose,rose_read,sizeof(rose_read));//从管道文件中读取数据
			printf("%s\n",rose_read);//打印数据
			write(fd_txt,rose_read,strlen(rose_read));//将收到的数据写到日志文件中
			if(strstr(rose_read,"bye")!=NULL)//判断收到的字符串中有“bye”就结束进程
			{
				close(fd_txt);
				close(jake_rose);
				kill(pid1,SIGKILL);
				kill(getpid(),SIGKILL);
				exit(0);
			}
			bzero(rose_read,100);//清空
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值