日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++禁止进程被结束_多进程任务实现

發布時間:2025/3/21 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++禁止进程被结束_多进程任务实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在調度系列文章的第一篇中我們提到調度是由好幾個模塊組成的,其中前面已經介紹了定時器,掃描模塊的相關實現知識點了,這里就繼續往后面的模塊介紹吧,那么接下來,我們就講下任務執行模塊吧。如果說任務調度系統系統,也許很多同學不知道是一個什么概念,但是如果說到crontab的話,大家可能就會恍然大悟了。任務調度系統其實就是一個比cron支持功能多點和復雜點的系統,但是他們本質上是一樣的,就是把任務管理起來,而其中調度系統和任務打交道的,也就是把任務調起來的模塊,就是任務執行模塊。而任務的存在方式也是有好多種的,用得比較多的幾種分別為可執行文件(主要指的是二進制文件命令行,當然,腳本也是通過命令行調起來,這里就不去糾結這個分類是否合理了),so以及腳本。由于文章篇幅的問題,我們把這幾種任務方式分成3篇博文來拆解,這次我們先來討論下怎樣調度二進制可執行文件構成的任務。

使用過命令行的同學都知道,我們使用命令行是一般是在shell中執行類似下面這樣的命令

/cmd/path/cmd_bin param1 param2 ... paramN

但是問題來了,任務調度系統又不能和shell交互,要怎樣調起這樣的命令呢?linux為我們提供了一套可行的方式,多進程。至于怎樣實現多進程的方式,我們從簡單到復雜來講吧

system()函數

在c標準庫中有一個system()函數,在調用這個函數時,linux會產生一個子進程,然后由子進程來調用/bin/sh-c string來執行參數string字符串所代表的命令。命令執行完后子進程退出,隨即返回原調用的進程。這個函數的原型如下

int system(const char * string); 產生一個子進程并執行參數中的命令行。參數string即要執行的命令

通過上面的分析可知,system()函數是完成能夠滿足我們的基本需求的,只要我們把要執行的命令拼裝成一個命令行,然后傳到system()函數即可。像下面例子所示

#include <stdlib.h> int main () {system("ls -lrt");return 0; }

但是,由于system()在命令執行完之前是會阻塞主進程的,這對于多個任務同時執行,而且任務都需要執行很長時間,并且我們需要知道每個任務的執行結果的情況下,system()就不能很好地滿足我們的需求了。雖然不能直接使用,但是我們可以參考下system()函數是怎樣實現的。

//c_standard_lib/STDLIB/SYSTEM.C/* UNIX system calls */ int _Execl(const char *, const char *, ...); int _Fork(void); int _Wait (int *);int (system)(const char *s){ /* send text to system command line processor */if (s){ /* not just a test */int pid = _Fork();if (pid < 0); /* fork failed */else if (pid == 0){ /* continue here as child */_Execl("/bin/sh", "sh", "-c", s, NULL);exit(EXIT_FAILURE);}else /* continue here as parent */while (_Wait(NULL) != pid); /* wait for child */}return (-1);}

從上面c標準庫的代碼中可以看到,在實現system()函數中使用到了3個其他系統函數,分別是fork(),execl()和wait()。既然如此,我們就順勢而為,看看能不能也使用這三個函數來實現一個滿足我們要求的做法。

自己動手,豐衣足食

上面我們知道了system()函數的用到了哪些系統調用,我們接下來就先熟悉下這些系統調用好了,原型如下

pid_t fork(void);fork()系統調用會通過復制一個現有進程來創建一個全新的進程。返回值:自進程中返回0,父進程返回進程id,出錯返回-1 int execl(const char *pathname, const char *arg, ... /* (char *) NULL */); int execlp(const char *file, const char *arg, ... /* (char *) NULL */); int execle(const char *pathname, const char *arg, ... /*, (char *) NULL, char * const envp[] */); int execv(const char *pathname, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvpe(const char *file, char *const argv[], char *const envp[]);在進程的創建上Unix采用了一個獨特的方法,它將進程創建與加載一個新進程映象分離。 當我們創建了一個進程之后,通常將子進程替換成新的進程映象,這可以用exec系列的函數來進行。 當然,exec系列的函數也可以將當前進程替換掉。path參數表示你要啟動程序的名稱包括路徑名 arg參數表示啟動程序所帶的參數,一般第一個參數為要執行命令名,不是帶路徑且arg必須以NULL結束 返回值:成功返回0,失敗返回-1 上述exec系列函數底層都是通過execve系統調用實現: int execve(const char *filename, char *const argv[],char *const envp[]);pid_t wait(int *wstatus); pid_t waitpid(pid_t pid, int *wstatus, int options);系統調用exit后,該進程并非馬上消失,而是留下一個叫僵尸進程的數據結構,僵尸進程是非常特使的一種,它放棄了幾乎所有的內存空間, 沒有任何可執行代碼,也不能別調度,僅僅在進程列表保留位置,而且不占用任何內存空間。wait()函數用于使父進程阻塞,直到一個子進程結束或者該進程接收到了一個指定的信號為止。 如果該父進程沒有子進程或者它的子進程已經結束,則wait()函數就會立即返回。waitpid()的作用和wait()一樣,但它并不一定要等待第一個終止的子進程(它可以通過pid指定需要等待終止的子進程),它還有若干options, 當options==WNOHANG時,相當于提供一個非阻塞版本的 wait()功能,也能支持作業控制。 實際上,wait()函數只是 waitpid()函數的一個特例,在Linux 內部實現 wait()函數時直接調用的就是waitpid()函數

下面是一個簡單的應用例子,在實際的應用中,除了這3個api的應用之外,還需要做很多其他的事情,如注冊信號,寫日志,管道重定向等等,有興趣的同學可以看看apue或者《linux系統編程》等等經典著作,這里就不再啰嗦了。

#include <functional> #include <iostream> #include <sstream> #include <algorithm> #include <sys/wait.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <signal.h> #include <unistd.h> #include <errno.h> #include <string.h>#include <agent/global.h> #include <agent/utility.h>int exec( const std::string& execName, std::vector<std::string>& params) {/*** Step 1. prepare argv*/std::vector<char*> argv;argv.resize(1024);argv[1023] = NULL;argv[0] = const_cast<char*> (execName.c_str());size_t N = params.size();N = (N > 1022) ? 1022 : N;int argc = 1;for (size_t i = 0; i < N; i++){argv[argc++] = const_cast<char*> (params.at(i).c_str());}argv[argc] = NULL;/*** Step 3. Fork and exec*/pid_t pid = fork();if (pid == 0){signal(SIGINT, SIG_IGN);// execexecvp(execName.c_str(), &argv[0]);_exit(-1); //不能用exit(),詳細原因參見apue}else if (pid > 0){/* parent process */int status = 0;pid_t nwait = waitpid(pid, &status, 0);while (nwait == -1 && errno == EINTR)nwait = waitpid(pid, &status, 0);if (nwait == -1){std::cout << "waitpid: " << strerror(errno) << std::endl;return -1;}// get exit value of child processint exit_value = 0;if (WIFEXITED(status)){// normally terminatedexit_value = WEXITSTATUS(status);}else if (WIFSIGNALED(status)){// killed or abortedexit_value = 0x80 | WTERMSIG(status);}elseexit_value = 0xf0;return exit_value;}return -1; }

怎樣做到的

本來打算對上述api的實現剖析一番的,但是想到自己已經很就沒有去看這么底層的東西了,而且linux內核版本更新得很快,所以就放棄了,只能奉上幾個api在內核中的實現代碼,有興趣的同學自行學習好了

fork()內核實現?elixir.bootlin.comwaitpid內核實現?elixir.bootlin.comexecve內核代碼?elixir.bootlin.com

總結

以上是生活随笔為你收集整理的c++禁止进程被结束_多进程任务实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国色综合 | 天天色综合av | 国产亚洲成av人在线观看导航 | 日韩一级网站 | 久久一二 | 麻豆免费观看视频 | 精品国产免费无码久久久 | 欧美日韩亚洲一区二区三区 | 快播av在线 | 9久9久9久女女女九九九一九 | 免费av视屏| www.av网址| 在线免费看毛片 | 国产极品久久久 | 午夜影院体验区 | 国产免费a级片 | 免费日韩成人 | 午夜天堂在线观看 | 樱桃视频一区二区三区 | 97精品视频在线观看 | 老女人综合网 | 国产一级片一区二区 | 中文在线中文资源 | 高清日韩一区 | 66av欧美| 久久免费精品 | 丁香六月天婷婷 | 影音先锋在线观看视频 | 亚欧三级| 黄色片视频免费在线观看 | 中文在线观看av | 久久999 | 91综合在线 | 亚洲欧美日韩在线 | 国产免费一区二区三区三州老师 | 国产网站免费观看 | 国产精品天天干 | 91打屁股 | 国产精品毛片一区二区在线看舒淇 | 亚洲无码久久久久 | 国产又爽又黄的激情精品视频 | 一区视频在线免费观看 | 在线cao| 久久人妻少妇嫩草av蜜桃 | 91少妇丨porny丨 | 久色视频在线观看 | 国产亚洲一区在线 | 久久久黄色网 | 亚洲乱码视频在线观看 | 精品欧美乱码久久久久久1区2区 | 婷婷网五月天 | 女人16一毛片 | 五月开心激情网 | 郑艳丽三级 | 美女又黄又爽 | 国产精品天天狠天天看 | 99九九精品视频 | www.555国产精品免费 | 欧美日韩在线看 | 亚洲精品福利在线观看 | 丰满人妻一区二区三区大胸 | 在线视频亚洲 | 美乳人妻一区二区三区 | 亚洲午夜久久久久 | 国产午夜精品理论片在线 | 色图av | av色播| 色综合加勒比 | 91久久国产综合久久 | 国产99免费视频 | 国产久精品 | 日本成人精品 | 成人免费毛片片v | 国产香蕉97碰碰碰视频在线观看 | 奇米色综合 | 日本涩涩视频 | 三浦惠理子aⅴ一二三区 | 免费黄色av网站 | 24小时日本在线www免费的 | 日韩精品一区二区三区四区 | 亚洲一区电影在线观看 | 69式视频 | 欧美影院一区二区三区 | 色综合色综合网色综合 | 脱女学生小内内摸了高潮 | 在线观看中文字幕亚洲 | 中文字幕电影一区二区 | 午夜久 | re久久| 黄色永久免费网站 | 521av在线 | 日韩r级电影在线观看 | 樱桃av | 欧美黑人又粗又大又爽免费 | 久草欧美 | 亚洲人午夜精品 | 欧美系列一区二区 | 国模无码国产精品视频 | 一区二区三区四区免费视频 |