Linux多工程式設計(三)---exec函式族及其基礎實驗
exec函式族
函式族說明
fork() 函式用於建立一個新的子程序,該子程序幾乎複製了父程序的全部內容,但是,這個新建立的子程序如何執行呢?exec 函式族就提供了一個在程序中啟動另一個程式執行的方法。它可以根據指定的檔名或目錄名找到可執行檔案,並用它來取代原呼叫程序的資料段、程式碼段和堆疊段,在執行完之後,原呼叫程序的內容除了程序號外,其他全部被新的程序替換了。另外,這裡的可執行檔案既可以是二進位制檔案,也可以是Linux下任何可執行的指令碼檔案。
在 Linux 中使用exec函式族主要有兩種情況:
● 當程序認為自己不能再為系統和使用者做出任何貢獻時,就可以呼叫 exec 函式族中的任意一個函式讓自己重生。
● 如果一個程序想執行另一個程式,那麼它就可以呼叫 fork() 函式新建一個程序,然後呼叫 exec 函式族中的任意一個函式,這樣看起來就像通過執行應用程式而產生了一個新程序(這種情況非常普遍)。
函式族語法
實際上,在Linux中並沒有exec()函式,而是由6個以 exec 開頭的函式,它們之間的語法有細微差別。下表列出了 exec 函式族的6個成員函式的語法:
這6個函式在函式名和使用語法的規則上都有細微的區別,下面就從可執行檔案查詢方式、引數傳遞方式和環境變數這幾個方面進行比較。
● 查詢方式:表1中的前4個函式的查詢方式都是完整的檔案目錄路徑,而最後兩個函式(也就是以 p 結尾的兩個函式)可以只給出檔名,系統就會自動按照環境變數“$PATH” 所指定的路徑進行查詢。
● 引數傳遞方式:exec函式族的引數傳遞有兩種:一種是逐個列舉的方式,而另一種則是將所有引數整體構造指標陣列傳遞。在這裡是以函式名的第5位字母來區分的,字母為 "l"(list)的表示逐個列舉引數的方式,其語法為const char *arg;字母為“v”(vector)的表示將所有引數整體構造指標陣列傳遞,其語法為 char *const argv[]。這裡的引數實際上就是使用者在使用這個可執行檔案時所需的全部命令選項字串(包括該可執行程式命令本身)。要注意的是,這些引數必須以NULL結束。
● 環境變數: exec函式族可以預設系統的環境變數,也可以傳入指定的環境變數。這裡以 “e”(environment)結尾的兩個函式 execle()和 execve()就可以在 envp[]中指定當前程序所使用的環境變數。
表2再對這6個函式中的函式名和對應語法做了一個小結,主要指出了函式名中每一位對應所表明的含義,以此表加以記住這6個函式。
事實上,這6個函式中真正的系統呼叫只有execve(),其他5個都是庫函式,它們最終都會呼叫execve()這個系統呼叫。在使用exec函式族時,一定要加上錯誤判斷語句。exec 很容易執行失敗,其中最常見的原因有:
① 找不到檔案或路徑,此時 errno 被設定為 ENOENT。
② 陣列argv 和envp 忘記用NULL結束,此時,errno被設定為 EFAUL。
③ 沒有對應可執行檔案的執行許可權,此時 errno 被設定為EACCES。
基礎實驗
實驗1
本實驗是為了說明如何使用檔名來查詢可執行檔案,同時使用引數列表的方式。這裡用的函式是 execlp()。程式程式碼如下:
在該程式中,首先使用 fork()函式建立一個子程序,然後在子程序中使用 execlp()函式。可以看到,這裡的引數列表列出了在 shell 中使用的命令名和選項,並且當使用檔名進行查詢時,系統會在預設的環境變數PATH中尋找該可執行檔案。
使用命令:gcc execlp.c -o execlp編譯後,然後再執行,結果如下圖:
使用env命令,可以檢視到環境變數的路徑名
此程式的執行結果與在shell中直接輸入命令“ps -ef”是一樣的,當然,在不同系統的不同時刻可能會有不同的結果。
實驗2
本實驗實現的功能和實驗1的一樣,不同的是使用的函式不同。本實驗將使用完整的檔案目錄來查詢對應的可執行檔案。注意,目錄必須以“/”開頭,否則將其視為檔名。程式程式碼如下:
編寫儲存原始檔,然後使用命令:gcc execl.c -o execl編譯,接著執行命令:./execl,可以看到實驗結果和實驗1一樣
實驗3
本實驗是利用execle()函式將環境變數新增到新建的子程序中,這裡的“env”是檢視當前程序環境變數的命令,實驗程式碼如下:
編寫儲存原始檔後,使用命令:gcc execle.c -o execle,再執行命令:./execle,執行結果如下圖
實驗4
本實驗實現功能和實驗3一樣,不同的是使用的execve()函式,通過構造指標陣列的方式來傳遞引數,注意引數列表一定要以NULL作為結尾識別符號,實驗程式碼如下:
編寫儲存原始檔,使用命令:gcc execve.c -o execve,再執行命令:./execve,結果如下:
到此關於程序的執行實驗完畢,下一節學習程序的終止
相關推薦
Linux多工程式設計(三)---exec函式族及其基礎實驗
exec函式族 函式族說明 fork() 函式用於建立一個新的子程序,該子程序幾乎複製了父程序的全部內容,但是,這個新建立的子程序如何執行呢?exec 函式族就提供了一個在程序中啟動另一個程式執行的方法。它可以根據指定的檔名或目錄名找到可執行檔案,並用它來取代原呼叫程序
Linux 多工程式設計——程序替換:exec 函式族
在 Windows 平臺下,我們可以通過雙擊執行可執行程式,讓這個可執行程式成為一個程序;而在 Linux 平臺,我們可以通過 ./ 執行,讓一個可執行程式成為一個程序。 但是,如果我們本來就執行著一個程式(程序),我們如何在這個程序內部啟動一個外部程式,由核心將這個外部程式讀入記憶體
Linux多工程式設計(六)---編寫多程序程式及其程式碼
實驗目的 通過編寫多程序程式,熟練掌握fork()、exec()、wait()和waitpid()等函式的使用,進一步理解在Linux中多程序程式設計的步驟。 實驗內容 該實驗有3個程序,其中一個為父程序,其餘兩個是該父程序建立的子程序,其中一個子程序執行“ls
Linux多工程式設計(七)---Linux守護程序及其基礎實驗
守護程序概述 守護程序,又叫daemon程序(不知怎的,我突然想起來吸血鬼日記中的達蒙了,很好看的美劇),是Linux中的後臺服務程序。他是一個生存期較長的程序,通常獨立於控制終端並且週期性地執行某種任務或者等待處理某些發生的事件。守護程序常常在系統引導載入時啟動,在
Linux多執行緒(三)執行緒清理函式
#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>void *clean_up(void *arg){ char *s= (char *)arg; pr
Linux 之檔案程式設計(三)
Linux之檔案程式設計中軟連結和硬連結的用法和區別前言:在Linux中使用什麼來識別一個檔案呢?我們先在終端上輸入命令: ls -i 看看會有什麼資訊出現。[email protected]:~$ ls -i顯示的資訊1048577 bin 5
linux 核心模組程式設計之編譯多個原始檔(三)
編譯擁有多個原始檔的核心模組的方式和編譯一個原始檔的方式差不多,我們先來看下我們需要的檔案都有哪些。 首先是main.c檔案 #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE
多線程編程之Linux環境下的多線程(三)
del mutex 我們 後退 post linux環境 ini tro create 前面兩篇文章都講述了Linux環境下的多線程編程基礎知識,也附帶了典型實例。本文主要比較一下Linux環境與Windows環境下的多線程編程區別。 看待技術問題要瞄準其本質,不管是W
linux學習筆記之shell程式設計(三)流程控制(3)---for迴圈
for迴圈 語法格式1:指定迴圈範圍 for 變數 in value1 value2... do something done 指令碼例項1 #!/bin/bash for i in 1 2
linux學習筆記之shell程式設計(三)流程控制(4)while迴圈和until迴圈
while迴圈和until迴圈 ###、 while迴圈 不定迴圈,程式碼格式: while [判斷] do something done 指令碼例項1: #!/bin/bash #從1加到
Linux入門實踐筆記(三)——資料盤格式化和和多分割槽掛載
[[email protected] ~]$ sudo fdisk /dev/vdb Welcome to fdisk (util-linux 2.23.2). Changes will remain in memory only, until you decide to write them.
linux下C 程式設計學習之多程序程式設計(一)
一、程序概念 程序是作業系統中資源分配的最小單位,而執行緒是排程的最小單位。 一個程序,主要包含三個元素: a) 一個可以執行的程式; b) 和該程序相關聯的全部資料(包括變數,記憶體空間,緩衝區等等); c) 程式的執行上下文(
Linux遠程桌面(三)
ets start isp bak onf x11 oda lin 修改 上一篇中的vnc配置已經很方便了,這一篇介紹更為簡單的xmanager的配置,xmanager畫面好一丟丟。
Linux 環境部署記錄(三) - Jenkins安裝與配置
版本 接下來 clas title col size pre 瀏覽器 jdk Jenkins安裝 為了兼容生產環境的jdk1.7版本,從官網得知,Jenkins必須是1.6之前的版本,因此下載jenkins-1.596.3-1.1.noarch.rpm到本地進行安裝: #移
Java多線程(三)SimpleDateFormat
spa bsp sdf java多線程 ext add println turn static 多線程報錯:java.lang.NumberFormatException: multiple points SimpleDateFormat是非線程安全的,在多線程情況下會有
linux一些基本常識(三)
sta oca 幫助文檔 spa onf mov 源碼安裝 依賴 undle acl:對本身權限的擴展 打包:zip 111.zip a.txt b.txt..... zip -r /etc/sysconfig/* (樣才能第歸所有內容0) 解寶:uzip
linux系統程序安裝(三)源碼包安裝程序
efi ron 下載 示例 wget 問題 位置 提示 /usr 源碼包安裝是日常使用過程中最經常的安裝方式,比如nagios套件、apche等重要軟件都是源碼包方式安裝,源碼包編譯安裝技術是運維技術中比較重要的部分。 一、源碼包安裝位置 運維時,最好把要跑的業務包放到/u
Linux系統管理初步(三) Linux網絡管理(一)(編輯中)
中斷 網絡 lin 命令 連接 nag shell sha 系統管理 Linux網絡管理(一) 一、ifconfig命令ifconfig命令可以顯示網卡及ip參數,在centos6中是比較重要的命令。 使用示例:1、網卡停止與網卡啟動 ifdown (網卡名)ifup
Linux驅動入門篇(三):基本的字符設備模塊(2)
連接 truct ace alloc orm 負數 -s tabs idt 上一節中介紹了設備號的申請和釋放,這一節開始了解字符設備的相關操作。 首先定位到<linux/cdev.h>文件,查看內核提供給字符設備的接口。 cdev結構 str
Linux 編程筆記(三)
操作 blog 簡單 語法 新的 包含 idt linux 操作 ash 上一章節對文件的基本屬性做了一個筆記,續上次筆記對Linux文件的屬性和屬性組做一筆記 我安裝的是虛擬機操作系統的版本還KaliLinux但是系統啟動速度拖延,所以剛開始還是配置Centos