IT培训机构|91免费精品视频|专注编程培训|91免费精品|软件开发培训_91免费国产视频_华清远见教育

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > linux進程間通信-FIFO,讓你全方位理解

linux進程間通信-FIFO,讓你全方位理解 時間:2018-06-20      來源:未知

有名管道(FIFO)

有名管道也被稱為FIFO文件,是一種特殊的文件。由于linux所有的事物都可以被視為文件,所以對有名管道的使用也就變得與文件操作非常統一。

(1)創建有名管道

用如下兩個函數中的其中一個,可以創建有名管道。

#include

#include

int mkfifo(const char *filename, mode_t mode);

filname是指文件名,而mode是指定文件的讀寫權限。

(2)打開有名管道

和打開其他文件一樣,可以用open來打開。通常有四種方法:

open(const char *path, O_RDONLY);

open(const char *path, O_RDONLY | O_NONBLOCK);

open(const char *path, O_WRONLY);

open(const char *path, O_WRONLY | O_NONBLOCK);

有三點要注意:

1就是程序不能以O_RDWR(讀寫)模式打開FIFO文件進行讀寫操作,而其行為也未明確定義,因為如一個管道以讀/寫方式打開,進程就會讀回自己的輸出,同時我們通常使用FIFO只是為了單向的數據傳遞。

2就是傳遞給open調用的是FIFO的路徑名,而不是正常的文件。(如:

const char *fifo_name = "/tmp/my_fifo";)

3第二個參數中的選項O_NONBLOCK,選項O_NONBLOCK表示非阻塞,加上這個選項后,表示open調用是非阻塞的,如果沒有這個選項,則表示open調用是阻塞的。

(3)阻塞問題

對于以只讀方式(O_RDONLY)打開的FIFO文件,如果open調用是阻塞的(即第二個參數為O_RDONLY),除非有一個進程以寫方式打開同一個FIFO,否則它不會返回;如果open調用是非阻塞的的(即第二個參數為O_RDONLY | O_NONBLOCK),則即使沒有其他進程以寫方式打開同一個FIFO文件,open調用將成功并立即返回。

對于以只寫方式(O_WRONLY)打開的FIFO文件,如果open調用是阻塞的(即第二個參數為O_WRONLY),open調用將被阻塞,直到有一個進程以只讀方式打開同一個FIFO文件為止;如果open調用是非阻塞的(即第二個參數為O_WRONLY | O_NONBLOCK),open總會立即返回,但如果沒有其他進程以只讀方式打開同一個FIFO文件,open調用將返回-1,并且FIFO也不會被打開。

(4)使用FIFO實現進程間的通信

管道的寫入端從一個文件讀出數據,然后寫入寫管道。管道的讀取端從管道讀出后寫到文件中。

寫入端代碼:fifowrite.c

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

const char *fifo_name = "/tmp/my_fifo";

int pipe_fd = -1;

int data_fd = -1;

int res = 0;

const int open_mode = O_WRONLY;

int bytes_sent = 0;

char buffer[PIPE_BUF + 1];

int bytes_read = 0;

if(access(fifo_name, F_OK) == -1)

{

printf ("Create the fifo pipe.\n");

res = mkfifo(fifo_name, 0777);

if(res != 0)

{

fprintf(stderr, "Could not create fifo %s\n", fifo_name);

exit(EXIT_FAILURE);

}

}

printf("Process %d opening FIFO O_WRONLY\n", getpid());

pipe_fd = open(fifo_name, open_mode);

printf("Process %d result %d\n", getpid(), pipe_fd);

if(pipe_fd != -1)

{

bytes_read = 0;

data_fd = open("Data.txt", O_RDONLY);

if (data_fd == -1)

{

close(pipe_fd);

fprintf (stderr, "Open file[Data.txt] failed\n");

return -1;

}

bytes_read = read(data_fd, buffer, PIPE_BUF);

buffer[bytes_read] = '\0';

while(bytes_read > 0)

{

res = write(pipe_fd, buffer, bytes_read);

if(res == -1)

{

fprintf(stderr, "Write error on pipe\n");

exit(EXIT_FAILURE);

}

bytes_sent += res;

bytes_read = read(data_fd, buffer, PIPE_BUF);

buffer[bytes_read] = '\0';

}

close(pipe_fd);

close(data_fd);

}

else

exit(EXIT_FAILURE);

printf("Process %d finished\n", getpid());

exit(EXIT_SUCCESS);

}

管道讀取端: fiforead.c

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

const char *fifo_name = "/tmp/my_fifo";

int pipe_fd = -1;

int data_fd = -1;

int res = 0;

int open_mode = O_RDONLY;

char buffer[PIPE_BUF + 1];

int bytes_read = 0;

int bytes_write = 0;

memset(buffer, '\0', sizeof(buffer));

printf("Process %d opening FIFO O_RDONLY\n", getpid());

pipe_fd = open(fifo_name, open_mode);

data_fd = open("DataFormFIFO.txt", O_WRONLY|O_CREAT, 0644);

if (data_fd == -1)

{

fprintf(stderr, "Open file[DataFormFIFO.txt] failed\n");

close(pipe_fd);

return -1;

}

printf("Process %d result %d\n",getpid(), pipe_fd);

if(pipe_fd != -1)

{

do

{

res = read(pipe_fd, buffer, PIPE_BUF);

bytes_write = write(data_fd, buffer, res);

bytes_read += res;

}while(res > 0);

close(pipe_fd);

close(data_fd);

}

else

exit(EXIT_FAILURE);

printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);

exit(EXIT_SUCCESS);

}

(5)有名管道的安全問題

有一種情況是:一個FIFO文件,有多個進程同時向同一個FIFO文件寫數據,而只有一個讀FIFO進程在同一個FIFO文件中讀取數據時,會發生數據塊的相互交錯。不同進程向一個FIFO讀進程發送數據是很普通的情況。這個問題的解決方法,就是讓寫操作的原子化。系統規定:在一個以O_WRONLY(即阻塞方式)打開的FIFO中, 如果寫入的數據長度小于等待PIPE_BUF,那么或者寫入全部字節,或者一個字節都不寫入。如果所有的寫請求都是發往一個阻塞的FIFO的,并且每個寫記請求的數據長度小于等于PIPE_BUF字節,系統就可以確保數據決不會交錯在一起。

上一篇:資深程序員告訴你串口配置的詳細流程,不容錯過

下一篇:imageview的基本屬性介紹,通俗易懂

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 太原重卡叔叔运输有限公司-山西太原大件运输、太原物流公司、太原货运物流、太原大件运输、太原货运信息、长治物流公司、长治大件运输、晋城物流公司、晋城大件运输、忻州大件运输、朔州大件运输、阳泉大件运输、大同大件运输、吕梁大件运输、临汾大件运输、运城大件运城 | 烟台天昊矿业有限公司、滑石、滑石粉、微细粉、滑石矿-烟台天昊矿业有限公司 | 立式离心泵_不锈钢自吸泵_液下泵_变频无负压供水设备-大东海泵业无锡有限公司 | 吸管包装机_塑料杯包装机_纸杯包装机_吸管挤出机_温州恩博机械有限公司 | 品牌策划-品牌设计-济南之式传媒广告有限公司官网-提供品牌整合丨影视创意丨公关活动丨数字营销丨自媒体运营丨数字营销 | 聚焦吉林-城市晚报官方网站| 武汉防雷检测_防雷工程设计施工_防雷设备材料_湖北普天科技有限公司 | 压力容器锻件_升高法兰_管板_阀体_接管锻件 - 山西中重重工集团 压力机-压装机-黄油机-黄油泵-[广东品嘉灵]专业定制各种精密压装设备 | 呼吸家官网|肺功能检测仪生产厂家|国产肺功能仪知名品牌|肺功能检测仪|肺功能测试仪|婴幼儿肺功能仪|弥散残气肺功能仪|肺功能测试系统|广州红象医疗科技有限公司|便携式肺功能仪|大肺功能仪|呼吸康复一体机|儿童肺功能仪|肺活量计|医用简易肺功能仪|呼吸康复系统|肺功能仪|弥散肺功能仪(大肺)|便携式肺功能检测仪|肺康复|呼吸肌力测定肺功能仪|肺功能测定仪|呼吸神经肌肉刺激仪|便携式肺功能 | 九江东盛机械制造有限公司| 盐城市城镇化建设投资集团有限公司[盐城国资企业、盐城国资集团、盐城文化旅游、盐城基础设施、盐城土地开发、盐城粮食收储] | 削片机|木材破碎机|木材粉碎机|模板破碎机|双轴撕碎机_郑州木工机械制造厂 | 铅板-济南鑫玉防辐射材料有限公司 | 明基太阳能玻璃钢污水处理公司-设计研发全自动加药装置设备 | 小程序商城,_电商系统源码,直播商城定制开发电商系统源码,电商系统,java电商系统 | 塑料凹版印刷机-干式复合机-分条机-涂布机生产厂家温州华印机械有限公司 | 新东方大学考试官网_考研/英语/雅思/托福/四六级/日语/韩语/教资在线网课官网 | 全铝家居_十大全铝家具品牌_全铝衣柜橱柜——佛山欧格美铝业 | 惠州清洁公司|惠州保洁公司|惠州清洁|惠州保洁|惠州清洁服务|惠州保洁服务|壹壹集团 | 整体滤板模板-S型塑料滤砖-MBBR生物悬浮球填料-微孔曝气器-大恒环保科技 | 洒水车_水车_洒水车价格_喷水车_绿化喷洒车_绿化洒水车- 程力专用汽车股份有限公司 | 世界地图,卫星地图,99地图网,微笑如歌 - www.99ditu.com | 盆底肌修复仪器-产后康复脉冲磁训练仪-南京佳澜健康管理有限公司 | 中空吹塑-PETG吹塑加工-吹塑玩具-东莞市鹏美塑胶五金有限公司 | 辽宁闻天香食品有限公司| 智能照明模块_智能照明控制器_照明控制系统_智能调光模块_西安邦华电气工程有限公司 | 景德镇市华信物业管理有限公司| 长焦监控摄像机-热成像夜视仪-激光云台-深圳红阳信息科技有限公司 | 上海熙隆光电科技有限公司-半导体激光器,一字线激光器,光纤耦合激光器,拉曼激光器 | 郑州月嫂|月嫂培训|月嫂服务|郑州布卢家政服务有限公司 | 首页|广东蒙泰高新纤维股份有限公司|丙纶细旦丝|丙纶异形丝|丙纶FDY网络丝 - 广东蒙泰高新纤维股份有限公司 | 研线网-考研网-考研科目/时间/专业-研线网 | 实木中药柜,实木中药斗,木制中药柜,木制中药柜的价格,实木中草药柜,安国美佳中药柜厂家 | 泊头压滤机-隔膜-洗沙-厢式-板框压滤机-河北巨盛压滤机制造有限公司 | 钻床,数控钻床,摇臂钻床,立式钻床_滕州市高地机床有限公司 | 净水器厂家_杭州净水器厂家_杭州拥政科技有限公司 | 山东礼品盒,礼品盒生产厂家,礼品包装盒厂家-济南恒印包装有限公司 | 长沙变频器维修,变频器维修,ABB变频器维修,西门子变频器维修,施耐德变频器维修,伺服驱动器维修,工业机器人维修,20年专业工控电气维修,长沙文铖电气设备有限公司_长沙文铖电气设备有限公司 | 青州东威机械有限公司,洗沙机,脱水筛、细沙回收机,淘金设备,洗石机,砂石分离机,筛沙机,采沙船,清淤船,破碎制砂机,海沙淡化设备 | 银马全自动免烧砖机设备厂家,提供免烧砖机价格报价及生产视频 | 天津实验室纯水机-GMP认证制药纯化水设备-天津开发区瑞尔环保科技有限公司 |