第一篇:Linux進程通信:命名管道FIFO小結(jié)(范文模版)
Linux下進程之間通信可以用命名管道FIFO完成。命名管道是一種特殊類型的文件,因為Linux中所有事物都是文件,它在文件系統(tǒng)中以文件名的形式存在。
在程序中,我們可以使用兩個不同的函數(shù)調(diào)用來建立管道:
#include
#include
int mkfifo(const char *filename, mode_t mode);
int mknode(const char *filename, mode_t mode | S_IFIFO,(dev_t)0);
下面先來創(chuàng)建一個管道:
view plaincopy to clipboardprint? #include
#include
#include
#include
int main()
{
int res = mkfifo(“/tmp/my_fifo”, 0777);
if(res == 0)
{
printf(“FIFO createdn”);
}
exit(EXIT_SUCCESS);
}
#include
int main(){
int res = mkfifo(“/tmp/my_fifo”, 0777);
if(res == 0)
{
printf(“FIFO createdn”);
}
exit(EXIT_SUCCESS);}
編譯這個程序:
gcc –o fifo1.c fifo
運行這個程序:
$./fifo1
用ls命令查看所創(chuàng)建的管道
$ ls-lF /tmp/my_fifo
prwxr-xr-x 1 root root 0 05-08 20:10 /tmp/my_fifo|
注意:ls命令的輸出結(jié)果中的第一個字符為p,表示這是一個管道。最后的|符號是由ls命令的-F選項添加的,它也表示是這是一個管道。
雖然,我們所設(shè)置的文件創(chuàng)建模式為“0777”,但它被用戶掩碼(umask)設(shè)置(022)給改變了,這與普通文件創(chuàng)建是一樣的,所以文件的最終模式為755。
打開FIFO一個主要的限制是,程序不能是O_RDWR模式打開FIFO文件進行讀寫操作,這樣做的后果未明確定義。這個限制是有道理的,因為我們使用FIFO只是為了單身傳遞數(shù)據(jù),所以沒有必要使用O_RDWR模式。如果一個管道以讀/寫方式打開FIFO,進程就會從這個管道讀回它自己的輸出。如果確實需要在程序之間雙向傳遞數(shù)據(jù),最好使用一對FIFO,一個方向使用一個。
當(dāng)一個Linux進程被阻塞時,它并不消耗CPU資源,這種進程的同步方式對CPU而言是非常有效率的。
有關(guān)Linux下命名管道FIFO的讀寫規(guī)則可以參見之前所寫的一篇文章:Linux命名管道FIFO的讀寫規(guī)則。
一、實驗:使用FIFO實現(xiàn)進程間通信
兩個獨立的程序:
1.生產(chǎn)者程序,它在需要時創(chuàng)建管道,然后盡可能快地向管道中寫入數(shù)據(jù)。
2.消費者程序,它從FIFO中讀取數(shù)據(jù)并丟棄它們。
生產(chǎn)者程序fifo2.c:
view plaincopy to clipboardprint? #include
#include
#include
#include
#include
#include
#include
#define FIFO_NAME “/tmp/Linux/my_fifo”
#define BUFFER_SIZE PIPE_BUF
#define TEN_MEG(1024 * 1024 * 10)
int main()
{
int pipe_fd;
int res;
int open_mode = O_WRONLY;
int bytes = 0;
char buffer[BUFFER_SIZE + 1];
if(access(FIFO_NAME, F_OK)==-1)
{
res = mkfifo(FIFO_NAME, 0777);
if(res!= 0)
{
fprintf(stderr, “Could not create fifo %sn”, FIFO_NAME);
exit(EXIT_FAILURE);
}
}
printf(“Process %d opening FIFO O_WRONLYn”, getpid());
pipe_fd = open(FIFO_NAME, open_mode);
printf(“Process %d result %dn”, getpid(), pipe_fd);
if(pipe_fd!=-1)
{
while(bytes < TEN_MEG)
{
res = write(pipe_fd, buffer, BUFFER_SIZE);
if(res ==-1)
{
fprintf(stderr, “Write error on pipen”);
exit(EXIT_FAILURE);
}
bytes += res;
}
close(pipe_fd);
}
else
{
exit(EXIT_FAILURE);
}
printf(“Process %d finishn”, getpid());
exit(EXIT_SUCCESS);
}
#include
#define FIFO_NAME “/tmp/Linux/my_fifo” #define BUFFER_SIZE PIPE_BUF #define TEN_MEG(1024 * 1024 * 10)
int main(){
int pipe_fd;
int res;
int open_mode = O_WRONLY;
int bytes = 0;
char buffer[BUFFER_SIZE + 1];
if(access(FIFO_NAME, F_OK)==-1)
{
res = mkfifo(FIFO_NAME, 0777);
if(res!= 0)
{
fprintf(stderr, “Could not create fifo %sn”, FIFO_NAME);
exit(EXIT_FAILURE);
}
}
printf(“Process %d opening FIFO O_WRONLYn”, getpid());
pipe_fd = open(FIFO_NAME, open_mode);
printf(“Process %d result %dn”, getpid(), pipe_fd);
if(pipe_fd!=-1)
{
while(bytes < TEN_MEG)
{
res = write(pipe_fd, buffer, BUFFER_SIZE);
if(res ==-1)
{
fprintf(stderr, “Write error on pipen”);
exit(EXIT_FAILURE);
}
bytes += res;
}
close(pipe_fd);
}
else
{
exit(EXIT_FAILURE);
}
printf(“Process %d finishn”, getpid());
exit(EXIT_SUCCESS);}
消費者程序fifo3.c:
view plaincopy to clipboardprint? #include
#include
#include
#include
#include
#include
#include
#define FIFO_NAME “/tmp/Linux/my_fifo”
#define BUFFER_SIZE PIPE_BUF
int main()
{
int pipe_fd;
int res;
int open_mode = O_RDONLY;
char buffer[BUFFER_SIZE + 1];
int bytes = 0;
memset(buffer, '