版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。
有名管道
有名管道是獨立于程序存在的
有名管道可以看成是有檔案名辨別的一個管道,不同于管道之處在于它提供一個路徑名與之關聯,以FIFO的檔案形式存在于檔案系統中。FIFO一旦建立,open、write、read、close操作跟普通檔案一樣(不支援諸如lseek()等檔案定位操作)。
建立管道
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
pathname:路徑名
mode:權限模式
類似的指令:mkfifo -m 模式 檔案名,如圖
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiIXZ05WZD9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwVeZRUTzMGVPNTT6hVdsdUZwZlMkZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DM4ATOzMjMyITMyMDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
删除管道
int unlink(const char *pathname);
open/read/write/close這幾個操作與普通檔案的操作一樣
阻塞/等待
讀端:open(O_RDONLY) 寫端:open(O_WRONLY)
注意:隻有讀端或者隻有寫端的時候,open函數都會阻塞
寫端關閉:隻剩下讀端時,讀端傳回0
讀端關閉:隻剩下寫端時,寫端會被禁止
代碼示範:
建立有名管道
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<stdlib.h>
int main()
{
if(mkfifo("myfifo", 0666) == -1)
{
perror("mkfifo");
exit(1);
}
return 0;
}
寫管道
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#define N 64
int main()
{
int fd;
char *s;
char buf[N];
if((fd = open("myfifo", O_WRONLY)) == -1)
{
perror("open");
exit(1);
}
while((s = fgets(buf, N, stdin)))
{
write(fd, buf, sizeof(buf));
if(strncmp(buf, "quit", 4) == 0)
break;
}
close(fd);
return 0;
}
讀管道
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#define N 64
int main()
{
int fd;
ssize_t n;
char buf[N];
if((fd = open("myfifo", O_RDWR)) == -1)
{
perror("open");
exit(1);
}
while(1)
{
if((n = read(fd, buf, N)) <= 0)
{
perror("read");
exit(1);
}
if(strncmp(buf, "quit", 4) == 0)
break;
printf("%s", buf);
}
close(fd);
return 0;
}
運作
注意:多個程序讀fifo,有名管道是一個隊列而不是一個普通檔案,寫端将位元組寫入隊列,而讀端從隊列的頭部移出位元組,每個讀端都會将資料移出隊列,是以如果想保證讀端都讀到資料,寫端必須要重寫資料,看圖
競态:
FIFO不會出現競态問題,read和write系統調用時原子操作。即讀取操作将管道清空,而寫入操作一次性将資料寫入或者将管道塞滿。在讀端和寫端連通之前,系統核心會将程序挂起。