這篇文章我們將介紹Linux間進程通間信中的有名管道與無名管道。 一.無名管道 無名管道是一種特殊類型的文件,在內核中對應的資源即一段特殊記憶體空間,這段空間完全由操作系統管理和維護。可以使用read/write等函數進行讀寫操作,但不能使用lseek函數來修改當前的讀寫位置,因為管道需要滿足FIFO ...
這篇文章我們將介紹Linux間進程通間信中的有名管道與無名管道。
一.無名管道
無名管道是一種特殊類型的文件,在內核中對應的資源即一段特殊記憶體空間,這段空間完全由操作系統管理和維護。可以使用read/write等函數進行讀寫操作,但不能使用lseek函數來修改當前的讀寫位置,因為管道需要滿足FIFO的原則。
讀寫無名管道:
讀寫管道使用的系統調用就是read和write,兩者都預設以阻塞方式讀寫管道,如果要修改這兩個函數的行為,可以使用fcntl函數實現。
讀寫特點:
利用無名管道實現子進程發送數據,父進程接收數據:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int filedes[2];
char buf[10] = {0};
pipe(filedes);
printf("Please input your string: \n");
if(fork() == 0)
{
close(filedes[0]);
while(1){
fgets(buf, 10, stdin);
int ret = write(filedes[1], buf, strlen(buf));
if(ret < 0)
break;
}
}
else
{
close(filedes[1]);
while(1){
int ret = read(filedes[0], buf, sizeof(buf));
if(ret < 0)
break;
printf("The msg that you input is : %s\n", buf);
printf("Please input your string: \n");
memset(buf, 0, sizeof(buf));
}
}
return 0;
}
二.有名管道
有名管道FIFO依賴於文件系統,是一個存在的特殊文件,因此,FIFO可以在同主機任意進程間實現通信。
有名管道雖然和普通文件一樣具有磁碟存放路徑、文件許可權和其他屬性;但是,它和普通文件又有區別,有名管道並沒有在磁碟中存放真正的信息,它存儲的通信信息在記憶體中,兩個進程結束後自動丟失,擁有的一個磁碟路徑僅僅是一個介面,其目的是使用進程間信息的編程更簡單統一。通信的兩個進程結束後,它的文件路徑本身仍然存在,這是和無名管道不一樣的地方。
讀寫有名管道:
通過write和read來操作有名管道前,需要調用open()函數打開該文件,另外,操作有名管道的阻塞位置為open位置,而不是無名管道的讀寫位置。
讀寫特點:
單進程讀寫有名管道:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFO_MODE 00600
#define FD_FLAG O_RDWR
int main(int argc, char** argv)
{
char buf[] = "Lance#";
char RecvBuf[20] = {0};
unlink(argv[1]);
mkfifo(argv[1], FIFO_MODE);
int fd = open(argv[1], FD_FLAG);
write(fd, buf, sizeof(buf));
read(fd, RecvBuf, sizeof(buf));
puts(RecvBuf);
return 0;
}
執行結果: