日韩性视频-久久久蜜桃-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++禁止进程被结束_多进程任务实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 日韩网站在线 | 最近更新中文字幕 | 永久免费精品视频 | 久久久久久久色 | 一区二区三区高清不卡 | 日本免费一级片 | 先锋资源在线视频 | 日本一级大片 | 奶水旺盛的少妇在线播放 | 一本大道久久久久精品嫩草 | 日本黄色一级视频 | 日韩精品一区二区在线看 | 国产超碰91 | 色欧美色 | www欧美日韩 | 欧美日韩中文字幕一区 | 黄色一级免费 | 日本毛片在线观看 | 少女情窦初开的第4集在线观看 | 色婷婷久| 免费视频久久久 | 国产美女久久久 | 日本美女日批视频 | 动漫一区二区三区 | 成年人看的免费视频 | 成人免费看片载 | 亚洲精品久久久乳夜夜欧美 | 亚洲爱爱网 | 国产精品成人一区二区三区电影毛片 | 亚洲综合大片69999 | 色天天av | 人人人妻人人澡人人爽欧美一区 | 午夜黄色网 | 绝顶高潮videos合集 | 亲子乱一区二区三区 | 欧美精品在线观看视频 | 中文字幕日韩国产 | xxx性欧美| 四虎影库永久在线 | 手机在线看片福利 | 91在线观看免费高清 | 一边吃奶一边摸做爽视频 | 潘金莲一级淫片免费放动漫 | 美日韩三级 | 久久久www成人免费无遮挡大片 | 国产日韩精品一区二区三区在线 | 久久久精品网站 | 国产99久久久国产精品成人免费 | 国产精品成人网站 | 国产一级片一区 | 国产欧美激情在线观看 | 风流老熟女一区二区三区 | 国产调教在线 | 亚洲最新在线视频 | 国产日韩精品久久 | 人人九九精品 | 男人的天堂在线播放 | 国产高潮网站 | 91蝌蚪少妇 | 欧美日本激情 | 欧美熟妇久久久久 | 国产精品视频福利 | 国产网站在线 | 国产又爽又猛又粗的视频a片 | 天天摸天天做 | 午夜影视免费 | 久久久久999 | 亚洲久久久久久久 | 中国免费黄色 | 一区二区三区精品视频在线观看 | 国产精品久久久久久久无码 | 69人妻精品久久无人专区 | 欧美sm凌虐视频网站 | 国产情侣啪啪 | 黄色大片中文字幕 | 7mav视频| 亚洲三级影视 | 久草网在线观看 | 亚洲国产成人一区二区 | 亚洲一区中文字幕在线观看 | 欧美爽爽爽 | 91麻豆一区二区三区 | 日韩中文电影 | 中文字幕二区 | 国产精品不卡在线观看 | 天天做天天爱天天操 | 欧美特级视频 | 狠狠天堂| 有码在线 | 亚洲熟妇丰满大屁股熟妇 | 毛片88| ktv做爰视频一区二区 | 中文字幕黄色片 | 亚洲欧美日韩精品久久亚洲区 | 毛片一级免费 | 可以在线看黄的网站 | 国产精品日韩一区二区三区 | 拔插拔插海外华人永久免费 | 日韩精品免费观看 |