亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人


Linux下多進(jìn)程編程之exec函數(shù)語(yǔ)法及使用實(shí)例

分享到:
           

    exec函數(shù)族

    1)exec函數(shù)族說(shuō)明

    fork()函數(shù)用于創(chuàng)建一個(gè)子進(jìn)程,該子進(jìn)程幾乎復(fù)制了父進(jìn)程的全部?jī)?nèi)容,但是,這個(gè)新創(chuàng)建的進(jìn)程如何執(zhí)行呢?exec函數(shù)族就提供了一個(gè)在進(jìn)程中啟動(dòng)另一個(gè)程序執(zhí)行的方法。它可以根據(jù)指定的文件名或目錄名找到可執(zhí)行文件,并用它來(lái)取代原調(diào)用進(jìn)程的數(shù)據(jù)段、代碼段和堆棧段,在執(zhí)行完之后,原調(diào)用進(jìn)程的內(nèi)容除了進(jìn)程號(hào)外,其他全部被新的進(jìn)程替換了。另外,這里的可執(zhí)行文件既可以是二進(jìn)制文件,也可以是Linux下任何可執(zhí)行的腳本文件。

    在Linux中使用exec函數(shù)族主要有兩種情況:
     ● 當(dāng)進(jìn)程認(rèn)為自己不能再為系統(tǒng)和用戶(hù)做出任何貢獻(xiàn)時(shí),就可以調(diào)用exec函數(shù)族中的任意一個(gè)函數(shù)讓自己重生。
     ● 如果一個(gè)進(jìn)程想執(zhí)行另一個(gè)程序,那么它就可以調(diào)用fork()函數(shù)新建一個(gè)進(jìn)程,然后調(diào)用exec函數(shù)族中的任意一個(gè)函數(shù),這樣看起來(lái)就像通過(guò)執(zhí)行應(yīng)用程序而產(chǎn)生了一個(gè)新進(jìn)程(這種情況非常普遍)。

    2)exec函數(shù)族語(yǔ)法

    實(shí)際上,在Linux中并沒(méi)有exec()函數(shù),而是有6個(gè)以exec開(kāi)頭的函數(shù),它們之間的語(yǔ)法有細(xì)微差別,本書(shū)在后面會(huì)詳細(xì)講解。

    表2列舉了exec函數(shù)族的6個(gè)成員函數(shù)的語(yǔ)法。

表2 exec函數(shù)族成員函數(shù)語(yǔ)法

所需頭文件 #include <unistd.h>
函數(shù)原型 int execl(const char *path, const char *arg, ...)
int execv(const char *path, char *const argv[])
int execle(const char *path, const char *arg, ..., char *const envp[])
int execve(const char *path, char *const argv[], char *const envp[])
int execlp(const char *file, const char *arg, ...)
int execvp(const char *file, char *const argv[])
函數(shù)返回值 -1:出錯(cuò)

    這6個(gè)函數(shù)在函數(shù)名和使用語(yǔ)法的規(guī)則上都有細(xì)微的區(qū)別,下面就從可執(zhí)行文件查找方式、參數(shù)傳遞方式及環(huán)境變量這幾個(gè)方面進(jìn)行比較。
     ● 查找方式。讀者可以注意到,表2中的前4個(gè)函數(shù)的查找方式都是完整的文件目錄路徑,而后兩個(gè)函數(shù)(也就是以p結(jié)尾的兩個(gè)函數(shù))可以只給出文件名,系統(tǒng)就會(huì)自動(dòng)按照環(huán)境變量“$PATH”所指定的路徑進(jìn)行查找。
     ● 參數(shù)傳遞方式。exec函數(shù)族的參數(shù)傳遞有兩種方式:一種是逐個(gè)列舉的方式,而另一種則是將所有參數(shù)整體構(gòu)造指針數(shù)組傳遞。在這里是以函數(shù)名的第5位字母來(lái)區(qū)分的,字母為“l(fā)”(list)的表示逐個(gè)列舉參數(shù)的方式,其語(yǔ)法為const char *arg;字母為“v”(vertor)的表示將所有參數(shù)整體構(gòu)造指針數(shù)組傳遞,其語(yǔ)法為char *const argv[]。讀者可以觀察execl()、execle()、execlp()的語(yǔ)法與execv()、execve()、execvp()的區(qū)別,它們的具體用法在后面的實(shí)例講解中會(huì)具體說(shuō)明。

    這里的參數(shù)實(shí)際上就是用戶(hù)在使用這個(gè)可執(zhí)行文件時(shí)所需的全部命令選項(xiàng)字符串(包括該可執(zhí)行程序命令本身)。要注意的是,這些參數(shù)必須以NULL結(jié)束。
     ● 環(huán)境變量。exec函數(shù)族可以默認(rèn)系統(tǒng)的環(huán)境變量,也可以傳入指定的環(huán)境變量。這里以“e”(environment)結(jié)尾的兩個(gè)函數(shù)execle()和execve()就可以在envp[]中指定當(dāng)前進(jìn)程所使用的環(huán)境變量。

    表3再對(duì)這6個(gè)函數(shù)中的函數(shù)名和對(duì)應(yīng)語(yǔ)法做了一個(gè)小結(jié),主要指出了函數(shù)名中每一位所表明的含義,希望讀者結(jié)合此表加以記憶。

表3 exec函數(shù)名對(duì)應(yīng)含義

前4位 統(tǒng)一為:exec
第5位 l:參數(shù)傳遞為逐個(gè)列舉方式 execl、execle、execlp
v:參數(shù)傳遞為構(gòu)造指針數(shù)組方式 execv、execve、execvp
第6位 e:可傳遞新進(jìn)程環(huán)境變量 execle、execve
p:可執(zhí)行文件查找方式為文件名 execlp、execvp

    事實(shí)上,這6個(gè)函數(shù)中真正的系統(tǒng)調(diào)用只有execve(),其他5個(gè)都是庫(kù)函數(shù),它們終都會(huì)調(diào)用execve()這個(gè)系統(tǒng)調(diào)用。在使用exec函數(shù)族時(shí),一定要加上錯(cuò)誤判斷語(yǔ)句。exec很容易執(zhí)行失敗,其中常見(jiàn)的原因有:
     ● 找不到文件或路徑,此時(shí)errno被設(shè)置為ENOENT。
     ● 數(shù)組argv和envp忘記用NULL結(jié)束,此時(shí)errno被設(shè)置為EFAUL。
     ● 沒(méi)有對(duì)應(yīng)可執(zhí)行文件的運(yùn)行權(quán)限,此時(shí)errno被設(shè)置為EACCES。

    3)exec使用實(shí)例

    下面的第一個(gè)示例說(shuō)明了如何使用文件名的方式來(lái)查找可執(zhí)行文件,同時(shí)使用參數(shù)列表的方式。這里用的函數(shù)是execlp()。

    /* execlp.c */
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
        if (fork() == 0)
        {
            /* 調(diào)用execlp()函數(shù),這里相當(dāng)于調(diào)用了“ps –ef”命令 */
            if ((ret = execlp("ps", "ps", "-ef", NULL)) < 0)
            {
                printf("Execlp error\n");
            }
        }
    }

    在該程序中,首先使用fork()函數(shù)創(chuàng)建一個(gè)子進(jìn)程,然后在子進(jìn)程中使用execlp()函數(shù)。讀者可以看到,這里的參數(shù)列表列出了在shell中使用的命令名和選項(xiàng),并且當(dāng)使用文件名進(jìn)行查找時(shí),系統(tǒng)會(huì)在默認(rèn)的環(huán)境變量PATH中尋找該可執(zhí)行文件。讀者可將編譯后的結(jié)果下載到目標(biāo)板上,運(yùn)行結(jié)果如下:

    $ ./execlp
    PID TTY    Uid    Size    State    Command
    1          root   1832    S        init
    2          root   0       S        [keventd]
    3          root   0       S        [ksoftirqd_CPU0]
    4          root   0       S        [kswapd]
    5          root   0       S        [bdflush]
    6          root   0       S        [kupdated]
    7          root   0       S        [mtdblockd]
    8          root   0       S        [khubd]
    35         root   2104    S        /bin/bash /usr/etc/rc.local
    36         root   2324    S        /bin/bash
    41         root   1364    S        /sbin/inetd
    53         root   14260   S        /Qtopia/qtopia-free-1.7.0/bin/qpe -qws
    54         root   11672   S        quicklauncher
    65         root   0       S        [usb-storage-0]
    66         root   0       S        [scsi_eh_0]
    83         root   2020    R        ps -ef
    $ env
    …
    PATH=/Qtopia/qtopia-free-1.7.0/bin:/usr/bin:/bin:/usr/sbin:/sbin
    …

    此程序的運(yùn)行結(jié)果與在shell中直接輸入命令“ps -ef”是一樣的,當(dāng)然,在不同系統(tǒng)的不同時(shí)刻可能會(huì)有不同的結(jié)果。

    接下來(lái)的示例使用完整的文件目錄來(lái)查找對(duì)應(yīng)的可執(zhí)行文件。注意,目錄必須以“/”開(kāi)頭,否則將其視為文件名。

    /* execl.c */
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
        if (fork() == 0)
        {
            /* 調(diào)用execl()函數(shù),注意這里要給出ps程序所在的完整路徑 */
            if (execl("/bin/ps","ps","-ef",NULL) < 0)
            {
                printf("Execl error\n");
            }
        }
    }

    同樣將代碼下載到目標(biāo)板上運(yùn)行,運(yùn)行結(jié)果同上例。

    下面的示例利用execle()函數(shù)將環(huán)境變量添加到新建的子進(jìn)程中,這里的“env”是查看當(dāng)前進(jìn)程環(huán)境變量的命令,代碼如下:

    /* execle.c */
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
        /* 命令參數(shù)列表,必須以NULL結(jié)尾 */
        char *envp[]={"PATH=/tmp","USER=david", NULL};

        if (fork() == 0)
        {
            /* 調(diào)用execle()函數(shù),注意這里也要指出env的完整路徑 */
            if (execle("/usr/bin/env", "env", NULL, envp) < 0)
            {
                printf("Execle error\n");
            }
        }
    }

    下載到目標(biāo)板后的運(yùn)行結(jié)果如下:

    $ ./execle
    PATH=/tmp
    USER=sunq

    后一個(gè)示例使用execve()函數(shù),通過(guò)構(gòu)造指針數(shù)組的方式來(lái)傳遞參數(shù),注意參數(shù)列表一定要以NULL作為結(jié)尾標(biāo)識(shí)符。其代碼如下:

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
        /* 命令參數(shù)列表,必須以NULL結(jié)尾 */
        char *arg[] = {"env", NULL};
        char *envp[] = {"PATH=/tmp", "USER=david", NULL};

        if (fork() == 0)
        {
            if (execve("/usr/bin/env", arg, envp) < 0)
            {
                printf("Execve error\n");
            }
        }
    }

    下載到目標(biāo)板后的運(yùn)行結(jié)果如下:

    $ ./execve
    PATH=/tmp
    USER=david

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

   熱點(diǎn)鏈接:

   1、Linux下多進(jìn)程編程之fork()函數(shù)語(yǔ)法
   2、Linux下多進(jìn)程編程之fork()函數(shù)說(shuō)明
   3、Linux下多任務(wù)系統(tǒng)之線(xiàn)程介紹
   4、Linux下進(jìn)程的內(nèi)存結(jié)構(gòu)
   5、Linux下進(jìn)程的創(chuàng)建、執(zhí)行和終止

更多新聞>> 

主站蜘蛛池模板: 人人人人看人人人做人人 | 国产精品日本不卡一区二区 | 午夜视频久久 | 狠狠综合欧美综合欧美色 | 欧美成人性色生活片免费在线观看 | 国产成人高清亚洲一区久久 | 日本中文字幕在线视频站 | 久久99精品福利久久久 | 亚洲人影院 | 欧美成人四级剧情在线播放 | 黄色片韩国| 国产精品hd免费观看 | 精品久久国产 | 久操手机在线视频 | 国产一级视频久久 | 久久99视频免费 | 中文字幕日韩一区二区三区不卡 | 国产第一区二区三区在线观看 | 欧美一区二区三区免费不卡 | 免费香蕉成视频成人网 | 日本高清中文字幕一区二区三区 | 亚洲天堂网在线播放 | 一区二区三区不卡免费视频97 | 天天摸天天躁天天添天天爽 | 精品久久久一二三区 | 亚洲第一福利网 | 免费特级毛片 | 成人在线观看网址 | 久久综合九色综合欧美9v777 | 男女激情视频在线观看 | 日本xxxxx久色视频在线观看 | 国产大陆xxxx做受视频 | 久草资源在线播放 | jyzzjyzzjyzz日本在线观看 | 精品亚洲欧美高清不卡高清 | 国产一级毛片外aaaa | 综合视频网 | 久综合色 | seyeye在线网站免费观看视频 | 亚洲天堂久久精品成人 | 在线看的成人性视频 |