天天看點

程序間通信 一、傳統程序間通信(管道通信)

管道是UNIX系統最古老的的程序間通信方式(基本不再使用),曆史上的管道通常是半雙工(隻允許單項資料流動),現在的系統大都可以全雙工(資料可以雙向流動)

管道可分為無名管道和有名管道兩種;接下來将用代碼的形式介紹兩種管道實作程序間的通信。

一、 有名管道

指令:mkfifo
	函數:
	#include <sys/types.h>
	#include <sys/stat.h>
	Int  mkfifo(const char  *pathname, mode_t  mode);
		功能:建立管道檔案
		pathname:檔案路徑
		mode:權限
		傳回值:成功傳回0,失敗傳回-1
		
	***程式設計模型***
	程序A							程序B
	建立管道(mkfifo)				...
	打開管道(open)					打開管道
	讀/寫管道(read/write)			讀/寫資料
	關閉管道(close)				關閉管道
	删除管道(unlink)	            ...
           

有名管道程序A的實作代碼:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
	//1.打開管道檔案
	int fd = open("/tmp/fifo",O_RDONLY);
	if(0 > fd)
	{
		perror("open");
		return -1;
	}
	//2.讀資料
	while(1)
	{
		char buf[1024] = {};
		read(fd,buf,sizeof(buf));
		if(0 == strcmp(buf,"quit"))
		{
			printf("退出\n");
			break;
		}
		printf("read:%s\n",buf);
	}
	//關閉管道檔案
	close(fd);

	return 0;	
}

           

有名管道程序B的實作代碼

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main()
{
	//1.建立管道檔案,一般儲存在/tmp目錄下
	if(mkfifo("/tmp/fifo",0644))
	{
		perror("mkfifo");
		return -1;
	}
	//2.打開管道
	int fd = open("/tmp/fifo",O_WRONLY);
	if(0 > fd)
	{
		perror("open");
		return -1;
	}
	//3.寫資料
	char buf[1024] =  {};
	while(1)
	{
		printf(">");
		gets(buf);
		write(fd,buf,strlen(buf)+1);
		if(0 == strcmp(buf,"quit"))
		{
			printf("通信完成\n");
			break;
		}
	}
	//關閉管道檔案
	close(fd);
	return 0;	
}

           

二、無名管道

無名管道(用于通過fork建立的父子程序之間通信)
	#include <unistd.h>
int  pipe(int  pipefd[2]);
	功能:建立無名管道
	pipefd:用來存儲核心傳回的檔案描述
	pipefd[0] 用于讀操作
	pipefd[1] 用于寫操作
           

無名管道的實作代碼

#include<stdio.h>
#include<string.h>
#include<unistd.h>

int main()
{
	//建立管道
	int pipefd[2] = {};	
	//打開無名官道
	if(pipe(pipefd))
	{
		perror("pipe");
		return -1;
	}
	//建立程序,父程序寫關閉讀
	if(fork())
	{
		close(pipefd[0]);
		printf("父程序:%u\n",getpid());
		while(1)
		{
			char buf[1024] = {};
			usleep(1000);
			printf(">");
			gets(buf);
			write(pipefd[1],buf,strlen(buf)+1);
			if(0 == strcmp(buf,"quit"))
			{
				printf("通信結束\n");
				close(pipefd[1]);
				return 0;
			}
		}
	}
	else//子程序讀,關閉寫
	{
		close(pipefd[1]);
		printf("子程序:%u\n",getpid());
		while(1)
		{
			char buf[1024] = {};
			read(pipefd[0],buf,sizeof(buf));
			if(0 == strcmp(buf,"quit"))
			{
				printf("通信結束\n");
				close(pipefd[0]);
				return 0;
			}
			printf("read:%s\n",buf);
		}
	}
	return 0;	
}

           

繼續閱讀