歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux技術

linux中的命名管道(FIFO)

管道只能用於親緣關系之間的通信,而FIFO中,只要可以訪問路徑,就可以進行通信。

FIFO按照先進先出的原則進行通信,第一個被寫入的數據首先從管道中讀出。

創建命名管道的系統函數有兩個: mknod和mkfifo。兩個函數均定義在頭文件sys/stat.h,函數原型如下:

#include <sys/types.h>

#include <sys/stat.h>

int mknod(const char *path,mode_t mod,dev_t dev);

int mkfifo(const char *path,mode_t mode);

函數mknod參數中path為創建的命名管道的全路徑名: mod為創建的命名管道的模式,指明其存取權限; dev為設備值,該值取決於文件創建的種類,它只在創建設備文件時才會用到。這兩個函數調用成功都返回0,失敗都返回- 1。使用mknod函數創建了一個命名管道:

umask(0);

if (mknod("/tmp/fifo",S_IFIFO | 0666) == -1)

{

perror("mkfifo error");

exit(1);

}

函數mkfifo前兩個參數的含義和mknod相同。

umask(0);

if (mkfifo("/tmp/fifo",S_IFIFO|0666) == -1)

{

perror("mkfifo error!");

exit(1);

}

“S_IFIFO|0666”指明創建一個命名管道且存取權限為0666,即創建者、與創建者同組的用戶、其他用戶對該命名管道的訪問權限都是可讀可寫( 這需要注意umask對生成的管道文件權限的響)。

調用open()打開命名管道的進程可能會被阻塞。但如果同時用讀寫方式( O_RDWR)打開,則一定不會導致阻塞;如果以只讀方式( O_RDONLY)打開,則調用open()函數的進程將會被阻塞直到有寫方打開管道;同樣以寫方式( O_WRONLY)打開也會阻塞直到有讀方式打開管道。

對文件系統來說,匿名管道是不可見的,它的作用僅限於在父進程和子進程兩個進程間進行通信。而命名管道是一個可見的文件,因此,它可以用於任何兩個進程之間的通信,不管這兩個進程是不是父子進程,也不管這兩個進程之間有沒有關系。

fifo read端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define _PATH_ "/tmp/file.tmp"
#define _SIZE_ 100
int main()
{
	int fd = open(_PATH_, O_RDONLY);
	if (fd < 0){
		printf("open file error!\n");
		return 1;
	}
	char buf[_SIZE_];
	memset(buf, '\0', sizeof(buf));
	while (1){
		int ret = read(fd, buf, sizeof(buf));
		if (ret <= 0)//error or end of file
		{
			printf("read end or error!\n");
			break;
		}
		printf("%s\n", buf);
		if (strncmp(buf, "quit", 4) == 0){
			break;
		}
	}
	close(fd);
	return 0;
}
fifo write端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define _PATH_ "/tmp/file.tmp"
#define _SIZE_ 100
int main()
{
	int ret = mkfifo(_PATH_, 0666|S_IFIFO);
	if (ret == -1){
		printf("mkfifo error\n");
		return 1;
	}
	int fd = open(_PATH_, O_WRONLY);
	if (fd < 0){
		printf("open error\n");
	}
	char buf[_SIZE_];
	memset(buf, '\0', sizeof(buf));
	while (1){
		scanf("%s", buf);
		int ret = write(fd, buf, strlen(buf) + 1);
		if (ret < 0){
			printf("write error\n");
			break;
		}
		if (strncmp(buf, "quit", 4) == 0){
			break;
		}
	}
	close(fd);
	return 0;
}

Copyright © Linux教程網 All Rights Reserved