linux 管道 top,linux IPC总结——管道
管道
管道是unix ipc的最古老形式,是一種在內(nèi)存中的特殊文件,只能在具有公共祖先的進程之間使用(即父子進程,兄弟進程)。
管道由pipe函數(shù)創(chuàng)建
#include
int pipe(int fd[2])
fd[1]寫,fd[0]讀。
單個進程的管道幾乎沒有任何用處,通常,調(diào)用pipe的進程接著調(diào)用fork,這樣就創(chuàng)建了父子進程間的管道。
#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);//等待子進程結(jié)束
return 0;
}
輸出結(jié)果:
Father thread
Child Thread
Hello
當管道的一端關(guān)閉時:
當讀一個寫端關(guān)閉的管道時,則認為已經(jīng)讀到了數(shù)據(jù)的末尾,讀函數(shù)返回的讀出字節(jié)數(shù)為0;
當寫一個讀端關(guān)閉的管道時,向管道中寫入數(shù)據(jù)的進程將收到內(nèi)核傳來的SIFPIPE信號,應(yīng)用程序可以處理該信號,也可以忽略(默認動作則 ????? 是應(yīng)用程序終止)。
從管道中讀取數(shù)據(jù):
當管道的寫端存在時,如果請求的字節(jié)數(shù)目大于PIPE_BUF,則返回管道中現(xiàn)有的數(shù)據(jù)字節(jié)數(shù),如果請求的字節(jié)數(shù)目不大于PIPE_BUF,則返回管道中現(xiàn)有數(shù)據(jù)字節(jié)數(shù)(此時,管道中數(shù)據(jù)量小于請求的數(shù)據(jù)量);或者返回請求的字節(jié)數(shù)(此時,管道中數(shù)據(jù)量不小于請求的數(shù)據(jù)量)。注:PIPE_BUF在include/linux/limits.h中定義。
向管道中寫入數(shù)據(jù):
向管道中寫入數(shù)據(jù)時,linux將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進程就會試圖向管道寫入數(shù)據(jù)。如果讀進程不讀走管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將一直阻塞。
管道因為沒有名字所以只能用于具有親緣關(guān)系的進程,而有名管道(FIFO)則克服了這個限制。
FIFO
創(chuàng)建函數(shù)如下
#include #include
int mkfifo(const char *pathname, mode_t mode);
第一個參數(shù)是一個普通的路徑名,即為FIFO的名字。第二個參數(shù)設(shè)置權(quán)限,跟創(chuàng)建普通文件一樣。
FIFO的讀寫也像普通文件一樣,不過需要讀寫端都打開,具體規(guī)則如下:
當打開(open)時:
若沒有設(shè)置O_NONBLOCK,只讀open要阻塞到其它進程為寫而打開FIFO。類似地,只寫open要阻塞到其它進程為讀而打開FIFO。
如果設(shè)置了O_NONBLOCK,則只讀open立即返回,若沒有其它進程為寫而打開FIFO,則返回-1。
用FIFO模擬生產(chǎn)者消費者問題:
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;
}
結(jié)果如下:
可見讀進程運行0.013s就讀取了10m的數(shù)據(jù),FIFO的效率還是很高的。
總結(jié)
以上是生活随笔為你收集整理的linux 管道 top,linux IPC总结——管道的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hive 2.3 mysql_Note2
- 下一篇: linux 其他常用命令