linux 管道 top,linux IPC总结——管道
管道
管道是unix ipc的最古老形式,是一種在內存中的特殊文件,只能在具有公共祖先的進程之間使用(即父子進程,兄弟進程)。
管道由pipe函數創建
#include
int pipe(int fd[2])
fd[1]寫,fd[0]讀。
單個進程的管道幾乎沒有任何用處,通常,調用pipe的進程接著調用fork,這樣就創建了父子進程間的管道。
#include #include#include#include
intmain()
{int fd[2];char buf[80];
pid_t pid;
pipe(fd);
pid=fork();if(pid>0)
{//父進程
printf("Father thread");char s[]="Hello";
write(fd[1],s,sizeof(s));
close(fd[0]);
close(fd[1]);
}else if(pid==0)
{
printf("Child Thread");
read(fd[0],buf,sizeof(buf));
printf("%s",buf);
close(fd[0]);
close(fd[1]);
}
waitpid(pid,NULL,0);//等待子進程結束
return 0;
}
輸出結果:
Father thread
Child Thread
Hello
當管道的一端關閉時:
當讀一個寫端關閉的管道時,則認為已經讀到了數據的末尾,讀函數返回的讀出字節數為0;
當寫一個讀端關閉的管道時,向管道中寫入數據的進程將收到內核傳來的SIFPIPE信號,應用程序可以處理該信號,也可以忽略(默認動作則 ????? 是應用程序終止)。
從管道中讀取數據:
當管道的寫端存在時,如果請求的字節數目大于PIPE_BUF,則返回管道中現有的數據字節數,如果請求的字節數目不大于PIPE_BUF,則返回管道中現有數據字節數(此時,管道中數據量小于請求的數據量);或者返回請求的字節數(此時,管道中數據量不小于請求的數據量)。注:PIPE_BUF在include/linux/limits.h中定義。
向管道中寫入數據:
向管道中寫入數據時,linux將不保證寫入的原子性,管道緩沖區一有空閑區域,寫進程就會試圖向管道寫入數據。如果讀進程不讀走管道緩沖區中的數據,那么寫操作將一直阻塞。
管道因為沒有名字所以只能用于具有親緣關系的進程,而有名管道(FIFO)則克服了這個限制。
FIFO
創建函數如下
#include #include
int mkfifo(const char *pathname, mode_t mode);
第一個參數是一個普通的路徑名,即為FIFO的名字。第二個參數設置權限,跟創建普通文件一樣。
FIFO的讀寫也像普通文件一樣,不過需要讀寫端都打開,具體規則如下:
當打開(open)時:
若沒有設置O_NONBLOCK,只讀open要阻塞到其它進程為寫而打開FIFO。類似地,只寫open要阻塞到其它進程為讀而打開FIFO。
如果設置了O_NONBLOCK,則只讀open立即返回,若沒有其它進程為寫而打開FIFO,則返回-1。
用FIFO模擬生產者消費者問題:
fifo2.cpp:
#include#include#include#include#include#include#include#include#include#include
#define FIFO "/tmp/myfifo"
#define BUF_SIZE PIPE_BUF
#define SEND_MAX (1024*1024*10)
using namespacestd;intmain()
{intpid,fifo_fd;intsend_num;char *buf[BUF_SIZE+1];if(-1 ==access(FIFO,F_OK))
{int res = mkfifo(FIFO,0777);if(res != 0)
{
fprintf(stderr,"can't create fifo in %s",FIFO);
exit(EXIT_FAILURE);
}
}
fifo_fd=open(FIFO,O_WRONLY);
printf("process %d open fifo %d",getpid(),fifo_fd);if(fifo_fd == -1)
exit(EXIT_FAILURE);intres;while(send_num
{
res=write(fifo_fd,buf,BUF_SIZE);if(res == -1)
{
cout<
exit(EXIT_FAILURE);
}
send_num+=res;
}return 0;
}
fifo3.cpp
#include#include#include#include#include#include#include#include#include#include
#define FIFO "/tmp/myfifo"
#define BUF_SIZE PIPE_BUF
#define SEND_MAX (1024*1024*10)
using namespacestd;intmain()
{intfifo_fd;intres;char buffer[BUF_SIZE+1];int read_num = 0;
fifo_fd=open(FIFO,O_RDONLY);
printf("process %d open FIFO %d",getpid(),fifo_fd);if(fifo_fd == -1)
exit(EXIT_FAILURE);do{
res=read(fifo_fd,buffer,BUF_SIZE);
read_num+=res;
}while(res>0);
close(fifo_fd);return 0;
}
結果如下:
可見讀進程運行0.013s就讀取了10m的數據,FIFO的效率還是很高的。
總結
以上是生活随笔為你收集整理的linux 管道 top,linux IPC总结——管道的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hive 2.3 mysql_Note2
- 下一篇: chrome切换前端模式_H5暗黑模式在