Linux FIFO (進程間通信,生產者消費者)

上一篇中我們寫到了PIPE無名管道,的確是一種很方便的通信機制,但是其有一個缺點就是,PIPE是依賴於文件描述符的,並不在文件系統中維護,如果兩個通信進程之間沒有共同的祖先,他們就無法拿到相同的文件表項,所以沒有共同祖先的兩個進程是不能通過PIPE直接通信的。爲此Linux提供一種稱爲有名管道稱爲FIFO來解決,FIFO是一種全雙工的管道,先進先出,並且在磁盤有索引節點,這樣只要進程知道FIFO文件的路徑,就可以藉助FIFO通信了,FIFO和PIPE的底層實現幾乎是一樣的。下面我們演示一下PIPE中的程序換成兩個獨立運行的進程用FIFO來實現生產者消費者:

#include <iostream>
#include <unistd.h>
#include <vector>
#include <algorithm>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>

#define END_FLAG (1 << (sizeof(int)*8 - 1))

using namespace std;

#define FIFO_NAME "sort_fifo"

int main() {
    int fd = open(FIFO_NAME, O_RDWR);
    if(fd < 0) {
        return -1;
    }

#ifdef COSUMER
    cout<<"cosumer start\n";
    int data = -1;
    vector<int> v;
    while(read(fd, &data, sizeof(data)) > 0) {
        if(data == END_FLAG) {
            break;
        }
        v.push_back(data);
    }
    cout<<"size : "<<v.size()<<endl;
    sort(v.begin(), v.end());
    for(auto i : v) {
        cout<<i<<" ";
    }
    cout<<endl;
    cout<<"cosumer end\n";
#endif

#ifdef PRODUCTOR
    cout<<"productor start\n";
    int v[] = {134, 123, 1111, -1, 0, 888, 7564, 976, 9876, 66, 99, 123, 189};
    for(int i = 0; i < sizeof(v)/sizeof(v[0]); i++) {
        write(fd, &v[i], sizeof(v[i]));
    }
    int end = END_FLAG;
    write(fd, &end, sizeof(end));
    cout<<"productor end\n";
#endif
    return 0;
}
g++ -std=c++11 -o cosumer fifo_productor_cosumer.cpp -DCOSUMER
g++ -std=c++11 -o productor fifo_productor_cosumer.cpp -DPRODUCTOR
mkfifo sort_fifo

分別在兩個終端運行cosumer和productor就會看見結果,cosumer輸出如下:

$ ./cosumer
cosumer start
size : 13
-1 0 66 99 123 123 134 189 888 976 1111 7564 9876
cosumer end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章