1. 程式人生 > >linux c++多程序

linux c++多程序

當我們看恐怖片時,經常會有這樣的場景:當一個人被鬼上身後,這個人的身體表面上還和以前一樣,但是他的靈魂和思想已經被這個鬼佔有了,因此它會控制這個人做他自己想做的事情–那麼在程序中也有這樣的情景。那麼是如何實現的呢?現在我們來學習exec()函式族


一.exec()函式 族

1. 首先我們在終端輸入命令:man exec 可以看到函式的原型:

#include <unistd.h>
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*pathname, const char *argv[], char *const envp[]);
int execlp(const char *file, const char *arg, …);
int execvp(const char *file, char *const argv[]);
這些函式之間的第一個區別 是前4個取路徑名做引數,後兩個則取檔名做引數。
當指定filename做引數時:
a. 如果filename中包含/,則將其視為路徑名
b. 否則就按PATH環境變數搜尋可執行檔案。
PATH=/bin:/usr/bin:/user/local/bin:.
最後的路徑字首表示當前目錄。零字首耶表示當前目錄(在name=value開始處可用:表示,在中間用::表示,在行尾用:表示)
第二個區別 與引數表的傳遞有關(l表示list,v表示向量vector)。函式execl、execlp和execle要求將新程式的每個命令列引數都說明為一個單獨的引數,這中引數表以空指標結尾。而execv、execve和execvp則要先構造一個指向各引數的指標陣列,然後將該陣列的地址作為這三個函式的地址。
第三個區別 與向新程式傳遞環境表相關。函式execve和execle可以傳遞一個指向環境字串指標陣列的指標。

Tiger-John總結:
1>.其中只有execve是真正意義上的系統呼叫,其它都是在此基礎上經過包裝的庫函式。
2>.exec函式族的作用是根據指定的檔名找到可執行檔案,並用它來取代呼叫程序的內容 ,換句話說,就是在呼叫程序內部執行一個可執行檔案。這裡的可執行檔案既可以是二進位制檔案,也可以是任何Linux下可執行的指令碼檔案。

但是若為Shell指令碼時必須遵守以下的格式開頭:

第一行必須為: #!interpretername[arg]。其中interpretername可以時 shell或其他直譯器。例如,/bin/sh或/usr/bin/perl,arg是傳遞個直譯器的引數。


3>記憶方法:

l : 表示使用引數列表(list)

e:表示使用新的環境變數,不從當前繼承

p: 表示使用檔名,並從PATH環境進行搜尋

4> exec()函式族成功後是不會返回值的,因為程序的執行映像已經被替換,沒有接收返回值的地方了。但是若有一個錯誤的事件,將會返回-1.這些錯誤通常是有檔名或引數錯誤引起的。


2.exec()函式的功能:

1>exec()函式呼叫並沒有生成新程序,一個程序一旦呼叫exec函式,它本省就“死亡了”–就好比被鬼上身一樣,身體還是你的,但靈魂和思想已經被替換了 –系統把程式碼段替換成新的程式的程式碼,廢棄原有的資料段和堆疊段,併為新程式分配新的資料段與堆疊段,唯一保留的就是程序ID。也就是說,對系統而言,還是同一個程序,不過執行的已經是另外一個程式了。

2>執行exec()函式後的程序除了保持了原來的程序ID,父程序ID,實際使用者ID和實際組ID之外,程序還保持了其他許多原有特徵,主要有

a.當前工作目錄

b.根目錄

c.建立檔案時使用的遮蔽字

d.程序訊號遮蔽字。

e. 未決警告

f.和程序相關的使用處理器的時間

g.控制終端

h.檔案鎖
Tiger-John說明:

1.此處要分清只有fork()或vfork()函式才能建立一個新程序,而exec()函式時不能建立程序的。

2.因此在使用exec()函式之前,先要使用fork()或vfork()建立子程序後,子程序呼叫exec()函式來執行另外一個程式。

3.exec()函式族的具體實現

1>當程序呼叫一種exec()函式時,該程序執行的程式完全替換為新程式,而新程式則從main函式開始執 行 。因為呼叫exec()並不建立新程序,所以前後的程序ID不變。函式exec()只是用一個全新的程式替換當前程序的正文、資料、堆和棧段。
2>無論是哪個exec()函式,都是將可執行程式的路徑,命令列引數和環境變數3個引數傳遞個可執行程式的main()函式 。

3>具體介紹exec()函式族是如何main()函式需要的引數傳遞個它的。

a.execv()函式:execv()函式是通過路徑名方式呼叫可執行檔案作為新的程序映像。它的argv引數用來提供給main()函式的argv引數。argv引數是一個以NULL結尾的字串陣列

b.execve()函式:引數pathname時將要執行的程式的路徑名,引數argv,envp 與main()函式的argv,envp對應 。

c.execl()函式:次函式與execv函式用法類似。只是在傳遞argv 引數的時候,每個命令列引數都宣告為一個單獨的引數(引數中使用“……”說明引數的個數是不確定的),要注意的是這些引數要以一個空指標作為結束。

d.execle()函式:該函式與execl函式用法類似,只是要顯示指定環境變數。環境變數位於命令列引數最後一個引數的後面,也就是位於空指標之後。

e.execvp函式:該函式和execv函式用法類似,不同的是引數filename。該引數 如果包含/,則將其視為路徑名,否則就按PATH環境變數搜尋可執行檔案。

f.execlp()函式:該函式於execl函式類似,它們的區別和execvp與execv的區別一樣。

———————————————-

通過以上學習,我們來編個程式來體驗下它的執行過程

4.函式例項

exec.c

 #include<stdio.h>
 #include<sys/types.h>
 #include<unistd.h>
 #include<stdlib.h>
 int main(int argc,char *argv[],char ** environ)
 {
        pid_t pid;
        int status;
        printf("Exec example!\n");
        pid = fork();
         if(pid < 0)
        {
                 perror("Process creation failed\n");
                 exit(1);
        }
         else if(0 == pid)
         {
                 printf("child process is running\n");
                 printf("My pid = %d ,parentpid = %d\n",getpid(),getpid());
                 printf("uid = %d,gid = %d\n",getuid(),getgid());
                 execve("processimage",argv,environ);
                 printf("process never go to here!\n");
                 exit(0);
         }
         else {
                 printf("Parent process is runnig\n");
              }
        wait(&status);
        exit(0);
 }

processimage.c

  #include<stdio.h>
  #include<sys/types.h>
  #include<unistd.h>
  int main(int argc,char * argv[],char ** environ)
  {
          int i;

          printf("I am a process image!\n");
          printf("My pid =%d,parentpid = %d\n",getpid(),getppid());
          printf("uid = %d,gid = %d\n",getuid(),getpid());

          for(i = 0;i<argc;i++)
          {
                  printf("argv[%d]:%s\n",i,argv[i]);
          }

  } 

函式經過編譯:

[email protected]Ubuntu:~/work/process_thread/exec1gccprocessimage.coprocessimage<br>think@ubuntu:/work/processthread/exec1 gcc exec.c -o exec

[email protected]:~/work/process_thread/exec1$ ./exec test exec


函式執行結果:


Exec example!
Parent process is runnig
child process is running
My pid = 5949 ,parentpid = 5949
uid = 1000,gid = 1000
I am a process image!
My pid =5949,parentpid = 5948
uid = 1000,gid = 5949
argv[0]:./exec
argv[1]:test
argv[2]:exec
Tiger-John說明:

1.通過上面程式的執行,我們可以看到執行新程式的程序保持了原來程序的程序ID,父程序ID,實際使用者ID和實際組ID。

2. 當呼叫execve()函式後,原來的子程序的映像被替代,不再執行。

相關推薦

linux c++程序

當我們看恐怖片時,經常會有這樣的場景:當一個人被鬼上身後,這個人的身體表面上還和以前一樣,但是他的靈魂和思想已經被這個鬼佔有了,因此它會控制這個人做他自己想做的事情–那麼在程序中也有這樣的情景。那麼是如何實現的呢?現在我們來學習exec()函式族 一.exe

linux fork程序併發伺服器模型之C/C++程式碼實戰

        在很早的文章中, 我們一起聊過伺服器如何與多個客戶端進行通訊, 那時, 我們要麼用select, 要麼用多執行緒, 卻沒有用多程序。 其實, 多程序也可以實現與多個客戶端進行通訊。          如果是在while中迴圈accept,  然後迴圈處理事情

[pthread]Linux C 線程簡單示例

簡單 _exit bsp clas flags thread read arm color #include <stdio.h> #include <pthread.h> pthread_mutex_t mutex; pthread_con

Linux程式設計——程序程式設計

    本文學習Linux環境下的多程序程式設計,在我之前的文章裡已經講過程序與執行緒。本文,再簡單講一下程序的概念,方便接下來的學習。     程序定義:程序是一個具有一定獨立功能的程式的一次執行活動。     程序狀態圖:

Linux程式設計 程序執行緒求解PI(圓周率)

題目: 連結 多程序: #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define n 100000000.0 int main() { i

Linux程序執行緒之間的區別

http://blog.csdn.net/byrsongqq/article/details/6339240 網路程式設計中設計併發伺服器,使用多程序與多執行緒 ,請問有什麼區別?  答案一: 1,程序:子程序是父程序的複製品。子程序獲得父程序資料空間、堆和棧的複製品。 2,執行緒:相

linux c 執行緒開發

在開發多執行緒程式時,當建立的執行緒數量特別多的時候,就會遇到執行緒數量的瓶頸。 多執行緒設定 設定核心引數 kernel.threads-max kernel.threads-max 是 linux 系統允許建立的最大執行緒數,預設是 7767 修改 /etc/sysc

Linux C程式設計--程序介紹3--程序終止和等待

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

簡單的Linux C++執行緒CLOCK(時鐘)類

剛剛加入CSDN部落格,初來乍到也不知道寫什麼,所以來分享一個自己以前學C++的時候寫的第一個類,一個關於時鐘的簡單的Linux多執行緒CLOCK(時鐘)類: /***********************************************

PX4概念學習(1)——Linux程序執行緒基礎

【學習Freeape大神的uORB時,乘機補補有關Linux多程序、多執行緒的知識】 uORB(Micro Object Request Broker,微物件請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個模組,它肩負了整個系統的資料傳輸任務,所有的感測器資料

Linux c執行緒程式設計的4個例項

在主流的作業系統中,多工一般都提供了程序和執行緒兩種實現方式,程序享有獨立的程序空間,而執行緒相對於程序來說是一種更加輕量級的多工並行,多執行緒之間一般都是共享所在程序的記憶體空間的。   Linux也不例外,雖然從核心的角度來看,執行緒體現為一種對程序的"克隆"(clon

Linux程序執行緒基礎

【學習Freeape大神的uORB時,乘機補補有關Linux多程序、多執行緒的知識】 uORB(Micro Object Request Broker,微物件請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個模組,它肩負了整個系統的資料傳輸任務,所有的感測器資料、GPS、PPM訊

最簡單的實現Linux C++執行緒的互斥訪問

#include <stdlib.h> #include <string.h> #include <iostream> #include <unistd.h> #include <errno.h> #include <pthrea

Linux 實現程序拷貝檔案

//copy.c #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include<stdlib.h> #include<sys/stat.h> #include<e

[work] Linux Shell程序併發以及併發數控制

1. 基礎知識準備 1.1. linux後臺程序 Unix是一個多工系統,允許多使用者同時執行多個程式。shell的元字元&提供了在後臺執行不需要鍵盤輸入的程式的方法。輸入命令後,其後緊跟&字元,該命令就會被送往到linux後臺執行,而終端又可以繼續輸入下一個命令了。&nbs

linux fork 程序建立

1)fork函式將執行著的程式分成2個(幾乎)完全一樣的程序,每個程序都啟動一個從程式碼的同一位置開始執行的執行緒。 這兩個程序中的執行緒繼續執行,就像是兩個使用者同時啟動了該應用程式的兩個副本。 2)fork函式被呼叫一次但返回兩次。兩次返回的唯一區別是子程序中返回0值而父程序中返回子程序ID。

Linux伺服器程序模型

Linux多程序一般是master負責偵聽,worker接受和伺服client。 一個使用了以下技術的多程序模型: 1. sigset:安全訊號,訊號遮蔽和接受。 2. epoll:非同步io模型。 master程序使用訊號模型,偵聽使用者訊號和程式訊號,並和worker交流。

Linux C 執行緒程式設計總結

執行緒的資料處理   和程序相比,執行緒的最大優點之一是資料的共享性,各個程序共享父程序處沿襲的資料段,可以方便的獲得、修改資料。但這也給多執行緒程式設計帶來了許多問題。我們必須當心有多個不同的程序訪問相同的變數。許多函式是不可重入的,即同時不能執行一個函式的多個拷貝(除非使用不同的資料段)。在函式中宣告的

Linux C 執行緒程式設計】互斥鎖與條件變數

一、互斥鎖互斥量從本質上說就是一把鎖, 提供對共享資源的保護訪問。  1. 初始化:  在Linux下, 執行緒的互斥量資料型別是pthread_mutex_t. 在使用前, 要對它進行初始化:  對於靜態分配的互斥量, 可以把它設定為PTHREAD_MUTEX_INITIA

C++程序併發框架

轉自:http://blogread.cn/it/article/5630 三年來一直從事伺服器程式開發,一直都是忙忙碌碌,不久前結束了職業生涯的第一份工作,有了一個禮拜的休息時間,終於可以寫寫總結了。於是把以前的開原始碼做了整理和優化,這就是FFLIB。雖然這邊總結看起來