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


無名管道系統(tǒng)調(diào)用

分享到:
           

    本文關(guān)鍵字: linux 管道通信,linux 進(jìn)程通信方式 ,無名管道

    1.管道創(chuàng)建與關(guān)閉說明

    管道是基于文件描述符的通信方式,當(dāng)一個(gè)管道建立時(shí),它會(huì)創(chuàng)建兩個(gè)文件描述符fd[0]和fd[1],其中fd[0]固定用于讀管道,而fd[1]固定用于寫管道,如圖1所示,這樣就構(gòu)成了一個(gè)半雙工的通道。


圖1 無名管道的讀寫機(jī)制

    管道關(guān)閉時(shí)只需將這兩個(gè)文件描述符關(guān)閉即可,可使用普通的close()函數(shù)逐個(gè)關(guān)閉各個(gè)文件描述符。

    2.管道創(chuàng)建函數(shù)

    創(chuàng)建管道可以通過調(diào)用pipe()來實(shí)現(xiàn)。表1列出了pipe()函數(shù)的語法要點(diǎn)。

表1 pipe()函數(shù)語法要點(diǎn)

所需頭文件 #include <unistd.h>
函數(shù)原型 int pipe(int fd[2])
函數(shù)傳入值 fd[2]:管道的兩個(gè)文件描述符,之后就可以直接操作這兩個(gè)文件描述符
函數(shù)返回值 成功:0
出錯(cuò):-1

    3.管道讀寫說明

    用pipe()函數(shù)創(chuàng)建的管道兩端處于一個(gè)進(jìn)程中,由于管道是主要用于在不同進(jìn)程間通信的,因此在實(shí)際應(yīng)用中沒有太大意義。實(shí)際上,通常先是創(chuàng)建一個(gè)管道,再調(diào)用fork()函數(shù)創(chuàng)建一個(gè)子進(jìn)程,該子進(jìn)程會(huì)繼承父進(jìn)程所創(chuàng)建的管道,這時(shí),父子進(jìn)程管道的文件描述符對(duì)應(yīng)關(guān)系如圖2所示。


圖2 父子進(jìn)程管道的文件描述符對(duì)應(yīng)關(guān)系

    此時(shí)的關(guān)系看似非常復(fù)雜,實(shí)際上卻已經(jīng)給不同進(jìn)程之間的讀寫創(chuàng)造了很好的條件。父子進(jìn)程分別擁有自己的讀寫通道,為了實(shí)現(xiàn)父子進(jìn)程之間的讀寫,只需把無關(guān)的讀端或?qū)懚说奈募枋龇P(guān)閉即可。例如,在圖3中將父進(jìn)程的寫端fd[1]和子進(jìn)程的讀端fd[0]關(guān)閉。此時(shí),父子進(jìn)程之間就建立起了一條“子進(jìn)程寫入父進(jìn)程讀取”的通道。


圖3 關(guān)閉父進(jìn)程fd[1]和子進(jìn)程fd[0]

    同樣,也可以關(guān)閉父進(jìn)程的fd[0]和子進(jìn)程的fd[1],這樣就可以建立一條“父進(jìn)程寫入子進(jìn)程讀取”的通道。另外,父進(jìn)程還可以創(chuàng)建多個(gè)子進(jìn)程,各個(gè)子進(jìn)程都繼承了相應(yīng)的fd[0]和fd[1]。這時(shí),只需關(guān)閉相應(yīng)端口就可以建立其各子進(jìn)程間的通道。

    4.管道讀寫注意點(diǎn)

    管道讀寫需注意以下幾點(diǎn):

    ● 只有在管道的讀端存在時(shí),向管道寫入數(shù)據(jù)才有意義。否則,向管道寫入數(shù)據(jù)的進(jìn)程將收到內(nèi)核傳來的SIGPIPE信號(hào)(通常為Broken pipe錯(cuò)誤)。

    ● 向管道寫入數(shù)據(jù)時(shí),Linux將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進(jìn)程就會(huì)試圖向管道寫入數(shù)據(jù)。如果讀進(jìn)程不讀取管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將會(huì)一直阻塞。

    ● 父子進(jìn)程在運(yùn)行時(shí),它們的先后次序并不能保證。因此,為了保證父子進(jìn)程已經(jīng)關(guān)閉了相應(yīng)的文件描述符,可在兩個(gè)進(jìn)程中調(diào)用sleep()函數(shù)。當(dāng)然這種調(diào)用不是很好的解決方法,在后面學(xué)到進(jìn)程之間的同步機(jī)制與互斥機(jī)制后,請(qǐng)讀者自行修改本小節(jié)的實(shí)例程序。

    5.使用實(shí)例

    在本例中,首先創(chuàng)建管道,之后父進(jìn)程使用fork()函數(shù)創(chuàng)建子進(jìn)程,后通過關(guān)閉父進(jìn)程的讀描述符和子進(jìn)程的寫描述符,建立起它們之間的管道通信。

    /* pipe.c */
    #include <unistd.h>
    #include <sys/types.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX_DATA_LEN 256
    #define DELAY_TIME 1

    int main()
    {
        pid_t pid;
        int pipe_fd[2];
        char buf[MAX_DATA_LEN];
        const char data[] = "Pipe Test Program";
        int real_read, real_write;

        memset((void*)buf, 0, sizeof(buf));
        if (pipe(pipe_fd) < 0) /* 創(chuàng)建管道 */
        {
            printf("pipe create error\n");
            exit(1);
        }
        if ((pid = fork()) == 0) /* 創(chuàng)建一個(gè)子進(jìn)程 */
        {
            /* 子進(jìn)程關(guān)閉寫描述符,并通過使子進(jìn)程暫停1s等待父進(jìn)程已關(guān)閉相應(yīng)的讀描述符 */
            close(pipe_fd[1]);
            sleep(DELAY_TIME * 3);
            /* 子進(jìn)程讀取管道內(nèi)容 */
            if ((real_read = read(pipe_fd[0], buf, MAX_DATA_LEN)) > 0)
            {
                printf("%d bytes read from the pipe is '%s'\n", real_read, buf);
            }
            close(pipe_fd[0]); /* 關(guān)閉子進(jìn)程讀描述符 */
            exit(0);
        }
        else if (pid > 0)
        {
            /* 父進(jìn)程關(guān)閉讀描述符,并通過使父進(jìn)程暫停1s等待子進(jìn)程已關(guān)閉相應(yīng)的寫描述符 */
            close(pipe_fd[0]);
            sleep(DELAY_TIME);
            if((real_write = write(pipe_fd[1], data, strlen(data))) != -1)
            {
                printf("Parent wrote %d bytes : '%s'\n", real_write, data);
            }
            close(pipe_fd[1]); /* 關(guān)閉父進(jìn)程寫描述符 */
            waitpid(pid, NULL, 0); /* 收集子進(jìn)程退出信息 */
            exit(0);
        }
    }

    將該程序交叉編譯,下載到開發(fā)板上的運(yùn)行結(jié)果如下:

    $ ./pipe
    Parent wrote 17 bytes : 'Pipe Test Program'
    17 bytes read from the pipe is 'Pipe Test Program

    本文選自華清遠(yuǎn)見嵌入式培訓(xùn)教材《從實(shí)踐中學(xué)嵌入式Linux應(yīng)用程序開發(fā)》

   熱點(diǎn)鏈接:

   1、Linux下進(jìn)程間通信方式-管道
   2、Linux下進(jìn)程間通信
   3、實(shí)驗(yàn):編寫守護(hù)進(jìn)程
   4、實(shí)驗(yàn):編寫多進(jìn)程程序
   5、Linux守護(hù)進(jìn)程

更多新聞>> 

主站蜘蛛池模板: 喷淋清洗剂,铝合金清洗剂-青岛爱大生环保科技有限公司 | 河北永生食品有限公司,益宁挂面, 香海园 | 上饶环亚电脑会计培训学校--电脑学校|上饶电脑学校|上饶电脑培训|会计培训|上饶会计培训|上饶县会计培训|广丰会计培训|玉山会计培训|横峰会计培训|上饶网店培训 上进电缆(嘉兴)股份有限公司官网 - 光伏电缆|防火电缆|电力电缆|铝合金电缆专业生产厂家 | 火绒杀毒软件|火绒安全企业版_西南|四川|重庆|贵州|云南|西藏|成都火绒服务中心_成都火影科技有限公司-火绒安全|成都火影科技|火绒 | 山东发电机组生产厂家,特种火花塞生产厂家,高压线生产厂家,空气滤芯生产厂家,济南市博盛动力机械有限公司 | 真石漆-防火涂料-氟碳漆-地坪漆-广田外墙涂料 | ?神龙上古堂全国官网_颈腰椎调理服务中心_萨迦藏式秘方渗透法 | 煤炭烘干机|煤泥烘干机|矿泥烘干机|酒糟烘干机|果渣烘干机-东鼎干燥官方网站 | 基坑护栏,临边护栏网,爬架网,爬架网片,铁路防护栅栏,公路护栏网,河北昊坤金属制品有限公司 | 进销存软件|仓库管理软件|库存物资出入库|ERP生产|MRP|易特软件官方网站 | 智能电地暖_电地暖安装_电地暖价格-西安秦星暖通工程有限公司 | 深圳喜运达物流官网_东南亚物流|海运|专线|海外仓_泰国菲律宾马来西亚海运|物流专线|海外仓 | 太原铁艺围栏-山西泓宸辉铁艺工程有限公司 | 济南货架|济南仓储货架|济南仓库货架|山东蕴达金属制品有限公司 济南海纳特科技有限公司 | 直饮水设备-纯水设备-软化水设备 - 亿家清泉水处理设备厂家 | 慧泊中安,慧眼停车,慧泊社区,慧泊云,智慧停车云平台 | 矿用精确定位系统,井下4G无线通讯系统,工作面集控系统,皮带保护系统-山东新云鹏电气有限公司 | 四通球阀_304真空阀_不锈钢五通球阀厂家-浙江壬丰阀门有限公司 | 漫画大全免费看_漫画终身版_羞羞漫画网 | 无锡泡沫包装生产厂家-江阴源欧包装材料有限公司 | 日本国际高中学校招生【立学仕日本留学服务】日语中学学校|美术生|艺术生|高中生|本科|研究生|语言学校留学择校申请 | 江苏省阀门工业协会,江苏阀协| 航星洗涤机械有限公司_洗脱机_烘干机_烫平机_折叠机| 上海叶拓科技有限公司| 上海前 傲信息技术有限公司-企业信息化建设及品牌推广服务商 | 聊城市城乡规划设计研究院官方网站| 荆门市彩富机械有限责任公司|精铸件|五金|机械配件 | 碳纤维棒_碳纤维管_碳纤维缠绕管_嘉兴恒隆复合材料有限公司 | 上海舞台灯光音响租赁搭建线阵_年会演出摇头光束面光灯出租_led电子显示屏出租-上海led大屏幕租赁 | 九江中澳钽铌有限公司| 粮食烘干机|玉米烘干机|稻谷烘干机|小麦烘干机|大型连续烘干塔|500吨连续烘干塔|钢板仓|-郑州新光矿山机械制造有限公司 | 消防水电施工,消防水电安装,消防水电施工公司,消防水电改造-亿杰北京消防工程公司 | 上虞大金湖官网|数控外圆磨床|数控内圆磨床|数控无心磨床 | 呼吸家官网|肺功能检测仪生产厂家|国产肺功能仪知名品牌|肺功能检测仪|肺功能测试仪|婴幼儿肺功能仪|弥散残气肺功能仪|肺功能测试系统|广州红象医疗科技有限公司|便携式肺功能仪|大肺功能仪|呼吸康复一体机|儿童肺功能仪|肺活量计|医用简易肺功能仪|呼吸康复系统|肺功能仪|弥散肺功能仪(大肺)|便携式肺功能检测仪|肺康复|呼吸肌力测定肺功能仪|肺功能测定仪|呼吸神经肌肉刺激仪|便携式肺功能 | 苏子富春品牌馆 抚顺市富春农业科技开发有限公司 抚顺特色农产品 抚顺市特色馆 | 球磨机配件_烘干机配件_回转窑配件_球磨机小齿轮_球磨机大齿轮-巩义市兴农机械制造公司 | 木业信息网[www.wood186.com]全国木业建材服务平台 | 张家港起重搬运吊装,工厂设备搬运服务-张家港易源起重搬运有限公司 | 扬州市德友线缆有限公司-业从事高端特种线缆研发、制造、销售与服务。 | 学汽修,学汽修技术,汽修培训班,汽车美容培训,汽车新能源技术培训-广州万通汽车培训学校[官方网站] | 拉丝模|高晶异形拉丝模|联合拉拔机模具|钼丝拉丝模|金刚石纳米涂层模|焊丝拉丝模|钨钢拉丝模|聚晶拉丝模_河北恩泰利嘉金属制品有限公司 |