色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

文盤Rust--把程序作為守護進程啟動

jf_wN0SrCdH ? 來源:Rust語言中文社區(qū) ? 作者:Rust語言中文社區(qū) ? 2022-11-07 10:22 ? 次閱讀

當(dāng)我們寫完一個服務(wù)端程序,需要上線部署的時候,或多或少都會和操作系統(tǒng)的守護進程打交道,畢竟誰也不希望shell關(guān)閉既停服。今天我們就來聊聊這個事兒。

最早大家部署應(yīng)用的通常操作是 “nohup xxxx &”,別說像weblogic 或者其他java 容器有啟動腳本,里面其實也差不多;很喜歡 nginx的 -d 參數(shù),或者像redis 配置文件里可以指定是否以守護進程啟動。看起來很優(yōu)雅。

那么,使用rust 寫一個服務(wù)端程序能不能優(yōu)雅的使用一個參數(shù)指定應(yīng)用 daemon 模式啟動,同時使用stop 方式優(yōu)雅的停機呢?我們通過一個例子來說說基本的實現(xiàn)方式。

實例代碼依然集成在[interactcli-rs](https://github.com/jiashiwen/interactcli-rs)工程中。

首先來模擬一個啟動的服務(wù)進程 /src/server/server.rs

```rust
pub fn start(prefix: String) {
    for i in 0..1000 {
        println!("{}", prefix.clone() + &i.to_string());
        thread::sleep(Duration::from_secs(1));
    }
}
```
程序每秒輸出一個字符串,持續(xù)999秒,這個時間足夠驗證實驗結(jié)果了。

后臺啟動有兩個實現(xiàn),分別是利用[fork](github.com/immortal/fork) 或 [daemonize](github.com/knsd/daemonize),這兩個crate 實現(xiàn)原理類似,但在使用上稍有不同。

/src/cmd/cmdserver.rs,構(gòu)建了兩個啟動子命令,分別來調(diào)用 fork 和 daemonize的守護進程啟動實現(xiàn)。

```rust
pub fn new_server_cmd() -> Command {
    clap::new("server")
        .about("server")
        .subcommand(server_start_byfork())
        .subcommand(server_start_bydaemonize())
}


pub fn server_start_byfork() -> Command {
    clap::new("byfork")
        .about("start daemon by fork crate")
        .arg(
            Arg::new("daemon")
                .short('d')
                .long("daemon")
                .action(ArgAction::SetTrue)
                .help("start as daemon")
                .required(false),
        )
}
pub fn server_start_bydaemonize() -> Command {
    clap::new("bydaemonize")
        .about("start daemon by daemonize crate")
        .arg(
            Arg::new("daemon")
                .short('d')
                .long("daemon")
                .action(ArgAction::SetTrue)
                .help("start as daemon")
                .required(false),
        )
}
```
server 的子命令 byfork 啟動 通過 fork 實現(xiàn)的功能,bydaemonize 則調(diào)用通過 daemonize 的功能實現(xiàn)。

命令解析的代碼在 /src/cmd/rootcmd.rs 文件中。

先來看看基于 fork 的實現(xiàn):

```rust
if let Some(startbyfork) = server.subcommand_matches("byfork") {
    println!("start by fork");
    if startbyfork.get_flag("daemon") {
        let args: Vec = env::args().collect();
        if let Ok(Fork::Child) = daemon(true, false) {
            // 啟動子進程
            let mut cmd = Command::new(&args[0])
            for idx in 1..args.len() {
                let arg = args.get(idx).expect("get cmd arg error!");
                // 去除后臺啟動參數(shù),避免重復(fù)啟動
                if arg.eq("-d") || arg.eq("-daemon") {
                    continue;
                }
                cmd.arg(arg);
            
            let child = cmd.spawn().expect("Child process failed to start.");
            fs::write("pid", child.id().to_string()).unwrap();
            println!("process id is:{}", std::id());
            println!("child id is:{}", child.id());
        }
        println!("{}", "daemon mod");
        process::exit(0);
    }
    start("by_fork:".to_string());
}


```

首先,通過 Fork::daemon 函數(shù)派生出一個子進程;然后解析一下當(dāng)前命令,去掉 -d 參數(shù),構(gòu)建一個啟動命令,子命令啟動,退出父進程。這基本符合操作系統(tǒng)創(chuàng)建守護進程的過程 -- 兩次 fork。

再來看看基于 daemonize 的實現(xiàn):

```rust
if let Some(startbydaemonize) = server.subcommand_matches("bydaemonize") {
            println!("start by daemonize");
            let base_dir = env::current_dir().unwrap();
            if startbydaemonize.get_flag("daemon") {
                let stdout = File::create("/tmp/daemon.out").unwrap();
                let stderr = File::create("/tmp/daemon.err").unwrap();


                println!("{:?}", base_dir);


                let daemonize = Daemonize::new()
                    .pid_file("/tmp/test.pid") // Every method except `new` and `start`
                    .chown_pid_file(true) // is optional, see `Daemonize` documentation
                    .working_directory(base_dir.as_path()) // for default behaviour.          
                    .umask(0o777) // Set umask, `0o027` by default.
                    .stdout(stdout) // Redirect stdout to `/tmp/daemon.out`.
                    .stderr(stderr) // Redirect stderr to `/tmp/daemon.err`.
                    .privileged_action(|| "Executed before drop privileges");


                match daemonize.start() {
                    Ok(_) => {
                        println!("Success, daemonized");
                    }
                    Err(e) => eprintln!("Error, {}", e),
                }
            }
            println!("pid is:{}", std::id());
            fs::write("pid", process::id().to_string()).unwrap();
            start("by_daemonize:".to_string());
        }
```

首先獲取當(dāng)前的工作目錄,默認情況下 daemonize 會將工作目錄設(shè)置為 "/",為了避免權(quán)限問題,我們獲取當(dāng)前目錄作為守護進程的工作目錄。不知道是什么原因,在配置了pid_file 后,啟動守護進程時并沒在文件中有記錄 pid。不過也沒關(guān)系,我們可以在外部獲取并記錄守護進程的pid。

兩種方式啟動的守護進程均可在關(guān)閉shell的情況下維持進程運行。

從實現(xiàn)上來講,不論是 fork 還是 daemonize 都是 通過unsafe 方式調(diào)用了 libc api,類 unix 系統(tǒng)大多跑起來沒問題,windows 系統(tǒng)作者沒有驗證。

本期關(guān)于守護進程的話題就聊到這兒。

咱們下期見。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3795

    瀏覽量

    81300
  • Rust
    +關(guān)注

    關(guān)注

    1

    文章

    230

    瀏覽量

    6641

原文標(biāo)題:文盤Rust -- 把程序作為守護進程啟動

文章出處:【微信號:Rust語言中文社區(qū),微信公眾號:Rust語言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    深度無多配置一些經(jīng)驗心得

    的情況下,在安裝守護驅(qū)動前,個人一些建議,首先我們要確保intel 和amd的機器都能正常無啟動。大家都知道,網(wǎng)吧做母盤時,遇到在intel機器上做完的母盤拿到amd機器上藍屏的情況,這個本身是intel
    發(fā)表于 07-19 09:22

    Linux守護進程

    )是不能卸載的,這對以后的使用會造成諸多的麻煩(如系統(tǒng)由于某種原因要進入單用戶模式)。因此,通常的做法是讓“/”作為守護進程的當(dāng)前工作目錄,這樣就可以避免上述問題。當(dāng)然,如有特殊需要,也可以
    發(fā)表于 08-22 09:17

    【Linux學(xué)習(xí)雜談】之守護進程以及簡單創(chuàng)建

    首先我們需要了解一下什么叫做守護進程,以及我們?yōu)槭裁葱枰@樣的進程。我們知道當(dāng)我們寫一個簡單的程序的時候我們知道,這個程序比如說printf
    發(fā)表于 09-27 13:28

    升級程序作為一個單獨進程的方法

    步驟:升級程序作為一個單獨的進程1. 定時請求2. 對比版本號(使用正則匹配或字符串提取主版本號、次版本號、末版本號)3. 當(dāng)前版本號較小時下載升級資源包4. 備份當(dāng)前版本程序5. 解
    發(fā)表于 12-17 07:33

    Xtensa調(diào)試器守護進程在Linux中不工作的原因?怎么解決?

    試器守護進程” 中,我從路徑 /opt/xtensa/XtDevTools/downloads/RI-2021.8/tools/ 安裝 xt-ocd-14.08-linux64-installer。安裝
    發(fā)表于 03-21 08:39

    iny Linux有沒有辦法設(shè)置ssh或telnet守護進程可以在啟動后自動執(zhí)行?

    Linux 有沒有辦法設(shè)置ssh 或telnet 守護進程可以在啟動后自動執(zhí)行? 我們想在不通過控制臺的情況下使用 ssh 或 telnet 連接到微型 Linux。
    發(fā)表于 04-23 06:16

    守護進程的初級教程

    守護進程的初級教程,淺顯易懂,適合初學(xué)者
    發(fā)表于 06-17 16:16 ?0次下載

    Linux守護進程詳解

    較長的進程,通常獨立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。守護進程常常在系統(tǒng)引導(dǎo)載入時啟動,在系統(tǒng)關(guān)閉時終止。Linux有很多系統(tǒng)服務(wù),大多數(shù)服務(wù)都是通過
    發(fā)表于 10-18 14:24 ?0次下載
    Linux<b class='flag-5'>守護</b><b class='flag-5'>進程</b>詳解

    linux守護進程實例

      今天完成一個守護進程實驗。  1 熟悉守護進程編寫和調(diào)試(系統(tǒng)日志)  2 編寫多進程
    發(fā)表于 04-02 14:42 ?416次閱讀

    U啟動盤制作工具應(yīng)用程序免費下載

    本文檔的主要內(nèi)容詳細介紹的是U啟動盤制作工具應(yīng)用程序免費下載。
    發(fā)表于 04-24 08:00 ?5次下載
    U<b class='flag-5'>盤</b><b class='flag-5'>啟動盤</b>制作工具應(yīng)用<b class='flag-5'>程序</b>免費下載

    Linux 安全模塊:守護進程和套接字

    守護進程通常是在后臺觀察操作以等待狀態(tài)、服務(wù)于特定子系統(tǒng)并確定整個系統(tǒng)的操作規(guī)則的實用程序。例如,一個守護進程被配置為監(jiān)控打印服務(wù)的狀態(tài)。
    發(fā)表于 08-26 10:01 ?693次閱讀

    Rust -- rust連接oss

    我們以 [S3 sdk](https://github.com/awslabs/aws-sdk-rust)為例來說說基本的連接與操作,作者驗證過aws、京東云、阿里云。主要的增刪改查功能沒有什么差別。
    的頭像 發(fā)表于 05-12 16:18 ?621次閱讀

    Rust -- tokio綁定cpu實踐

    )。core_affinity_rs是一個用于管理CPU親和力的Rust crate。目前支持Linux、Mac OSX和Windows。官方宣稱支持多平臺,本人只做了linux 操作系統(tǒng)的測試。
    的頭像 發(fā)表于 06-11 15:32 ?596次閱讀
    <b class='flag-5'>文</b><b class='flag-5'>盤</b><b class='flag-5'>Rust</b> -- tokio綁定cpu實踐

    程序進程和線程的區(qū)別

    什么是進程 1、進程和線程的區(qū)別 進程是指正在運行的程序,它擁有獨立的內(nèi)存空間和系統(tǒng)資源,不同進程之間的數(shù)據(jù)不共享。
    的頭像 發(fā)表于 06-22 11:39 ?709次閱讀
    <b class='flag-5'>程序</b>中<b class='flag-5'>進程</b>和線程的區(qū)別

    Linux中如何編寫守護進程程序

    的一種進程,它們一般在系統(tǒng)啟動時開始運行,除非強行終止,否則直到系統(tǒng)關(guān)機都會保持運行。與守護進程相比,普通進程都是在用戶登錄或運行
    的頭像 發(fā)表于 10-07 17:12 ?668次閱讀
    Linux中如何編寫<b class='flag-5'>守護</b><b class='flag-5'>進程</b><b class='flag-5'>程序</b>
    主站蜘蛛池模板: 亚洲AV久久婷婷蜜臀无码不卡 | 欧美AAAAAA级午夜福利视频 | 青柠在线观看免费全集 | 在线播放日韩欧美亚洲日本 | 午夜精品久久久久久久99蜜桃 | 亚洲国产cao | www.狠狠色| 芒果影院网站在线观看 | 日本全彩黄漫无遮挡 | 精品夜夜澡人妻无码AV蜜桃 | 干了快生了的孕妇 | 高h肉肉乳共妻 | 亚洲免费人成在线视频观看 | a亚洲在线观看不卡高清 | 中文字幕一区在线观看视频 | 亚洲色图在线视频 | 爱穿丝袜的麻麻3d漫画acg | 美女张开腿露尿口给男人亲 | 国内精品久久久久影院男同志 | 十分钟免费视频大全在线观看 | 亚洲 色 欧美 爱 视频 日韩 | 伊人影院亚洲 | 男的插曲女的下面免费APP | 成人欧美一区二区三区白人 | 亚洲人美女肛交真人全程 | 99在线免费视频 | 午夜阳光影院在线观看视频 | 日韩欧美视频一区 | 午夜理论电影在线观看亚洲 | 欧美激情性AAAAA片欧美 | 综合网伊人 | 特级毛片全部免费播放免下载 | 绞尽奶汁by菊花开 | 先锋资源久久 | 俄罗斯呦呦| 欧美三级aaa | 成年人视频在线免费看 | 国语自产视频在线不卡 | 秋霞伦理电影在线看 | 欧美 另类 美腿 亚洲 无码 | 欧美激情视频二区 |