C++多進程編程

一、進程介紹

進程是指在操作系統中正在運行的一個程序,它在操作系統中佔有一定的資源,如內存、I/O、CPU時間等。

每個進程都有自己的地址空間,互相之間無法訪問,是通過操作系統提供的IPC(進程間通信)機制來進行進程間的通信和數據交互。

在C++中,可以通過一些庫函數來創建和控制進程的運行,如fork()、exec()、wait()等函數。

二、多進程編程

多進程編程是指同時運行多個進程,它可以提高程序的並發性和效率,對於系統性能和響應時間的要求高時非常有用。

在C++中,創建一個新進程可以使用fork()函數,它會複製父進程的所有資源,包括代碼、數據、棧、堆等,然後子進程繼續執行fork()函數後的語句,而父進程則返回子進程的進程ID,這樣父子進程可以在不同的代碼分支中執行不同的任務。

可以通過判斷fork()函數的返回值來確定當前代碼執行的是父進程還是子進程:

pid_t pid = fork();
if (pid == 0) {
    // 子進程
} else if (pid > 0) {
    // 父進程
} else {
    // 出錯處理
}

其中pid_t是一個整型類型,代表進程ID,如果pid等於0,則表示當前代碼執行的是子進程的分支;如果pid大於0,則表示當前代碼執行的是父進程的分支,pid就是子進程的進程ID;如果pid小於0,則表示創建新進程失敗。

除了fork()函數,還可以使用exec系列函數和wait()函數來控制進程的運行。

三、進程間通信

進程間通信(IPC)是指兩個或多個進程之間的數據交換和通信,可以使用多種方式進行進程間通信,常見的有管道、消息隊列、共享內存和信號量等。

其中,管道是最簡單的通信方式,它可以在兩個進程之間傳遞字符流,但只能用於具有親緣關係的進程之間通信(即通過fork()函數創建的父子進程);消息隊列可以傳遞複雜的數據結構,但如果數據量比較大時會影響性能;共享內存可以實現多個進程之間對同一塊內存的訪問,但需要解決進程同步和互斥的問題;信號量可以用來實現進程之間的同步和互斥,但需要掌握一定的信號量編程技巧。

下面是一個使用管道在父子進程之間傳遞數據的例子:

const int BUFFER_SIZE = 1024;
int pipe_fd[2];
char message[BUFFER_SIZE];
pid_t pid;

if (pipe(pipe_fd) < 0) {
    std::cerr << "create pipe error." << std::endl;
    exit(-1);
}

if ((pid = fork()) == -1) {
    std::cerr << "fork error." << std::endl;
    exit(-1);
} else if (pid == 0) {
    close(pipe_fd[1]);    // 關閉寫通道
    if (read(pipe_fd[0], message, BUFFER_SIZE) == -1) {
        std::cerr << "read error." << std::endl;
        exit(-1);
    }
    std::cout << "child process received message: " << message << std::endl;
    close(pipe_fd[0]);    // 關閉讀通道
} else {
    close(pipe_fd[0]);    // 關閉讀通道
    std::string input_message;
    std::cout << "input message to be sent to child process: ";
    std::getline(std::cin, input_message);
    if (write(pipe_fd[1], input_message.c_str(), input_message.size()) == -1) {
        std::cerr << "write error." << std::endl;
        exit(-1);
    }
    close(pipe_fd[1]);    // 關閉寫通道
    wait(NULL);           // 等待子進程結束
}

四、進程管理

進程管理是指對操作系統中的進程進行管理和調度,包括創建進程、終止進程、監控進程等操作,常用的進程管理工具有ps、top和kill等。

在C++中,可以使用系統函數kill()來終止一個進程,需要傳入進程ID和終止信號:

if (kill(pid, SIGKILL) == -1) {
    std::cerr << "kill process error." << std::endl;
    exit(-1);
}

其中,SIGKILL是一個宏定義,代表終止信號。

五、多進程編程實例

下面是一個簡單的多進程ping程序,它可以並行的ping多個IP地址,同時顯示結果:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

const int MAX_PROC_NUM = 10;
const int MAX_IP_NUM = 10;
const int MAX_RESULT_SIZE = 1024;

int proc_num = 0;
char ip_list[MAX_IP_NUM][16];

bool ping(const char* ip) {
    char cmd[1024] = {0};
    sprintf(cmd, "ping -c 4 %s", ip);
    FILE* pipe = popen(cmd, "r");
    if (!pipe) {
        return false;
    }

    char buffer[MAX_RESULT_SIZE];
    memset(buffer, 0, MAX_RESULT_SIZE);
    while (!feof(pipe)) {
        if (fgets(buffer, MAX_RESULT_SIZE, pipe)) {
            std::cout << buffer;
        }
    }

    if (pclose(pipe) == -1) {
        return false;
    }

    return true;
}

void handle_signal(int signo) {
    std::cout << "process " << getpid() << " received signal " << signo << std::endl;
    exit(signo);
}

void start_proc(int idx) {
    const char* ip = ip_list[idx];
    std::cout << "start ping " << ip << ", process id " << getpid() << std::endl;

    if (signal(SIGINT, handle_signal) == SIG_ERR) {
        std::cerr << "error setting signal handler." << std::endl;
        exit(-1);
    }

    ping(ip);

    std::cout << "ping " << ip << " finish, process id " << getpid() < 0) {
        std::cout << "process " << pid << " exit with status " << WEXITSTATUS(status) << std::endl;
        proc_num--;
    }
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "usage: " << argv[0] << " ip1 [ip2] [...]" < MAX_IP_NUM) {
        std::cerr << "too many ip addresses." << std::endl;
        return -1;
    }

    for (int i = 0; i < argc - 1; ++i) {
        strncpy(ip_list[i], argv[i + 1], sizeof(ip_list[i]));
    }

    for (int i = 0; i  0) {
            // parent
        } else {
            std::cerr << "fork process error." < 0) {
        check_procs();
        sleep(1);
    }

    return 0;
}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/235615.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 11:56
下一篇 2024-12-12 11:56

相關推薦

  • 如何通過jstack工具列出假死的java進程

    假死的java進程是指在運行過程中出現了某些問題導致進程停止響應,此時無法通過正常的方式關閉或者重啟該進程。在這種情況下,我們可以藉助jstack工具來獲取該進程的進程號和線程號,…

    編程 2025-04-29
  • Java中的殭屍進程簡介與解決方法

    本文將對Java中的殭屍進程進行詳細闡述,並給出幾種解決方法。 一、殭屍進程的概念 在操作系統中,進程是指正在執行的程序。當一個進程創建了一個子進程,而該子進程完成了任務卻沒有被父…

    編程 2025-04-27
  • 多線程和多進程的應用

    多線程和多進程是現代編程中常用的技術,可以提高程序的效率和性能。本文將從不同的角度對多線程和多進程進行詳細的介紹和應用。 一、多線程 vs 多進程 多線程和多進程都是為了實現程序並…

    編程 2025-04-27
  • Python多進程讀取數據

    本文將從多個方面詳細闡述在Python中如何通過多進程讀取數據,並給出完整的代碼示例。 一、多進程概述 在計算機科學中,進程是正在執行的程序實例。多進程是指計算機系統同時執行多個進…

    編程 2025-04-27
  • 進程a與進程b共享變量s1

    本文將從多個方面對進程a與進程b共享變量s1做詳細的闡述,並給出代碼示例。 一、定義全局變量s1 進程a與進程b共享變量s1,意味着s1是一個全局變量。在C語言中,可以使用關鍵字e…

    編程 2025-04-27
  • python多進程並行循環

    在大數據時代,我們通常需要處理大量的數據。處理大數據往往需要較長的時間,影響效率。Python提供了多線程、多進程等並行處理方式來提高數據處理效率。本文將主要講解python多進程…

    編程 2025-04-27
  • Python進程池共享內存用法介紹

    本文將從多個方面詳細闡述Python進程池共享內存的相關知識,包括如何使用進程池、進程池的實現原理、進程池中的共享內存管理等。本文內容將涵蓋: 一、進程池的使用 進程池是一種有效的…

    編程 2025-04-27
  • Linux守護進程

    一、什麼是Linux守護進程 Linux守護進程是在Linux系統下運行的一種特殊進程,它沒有終端連接,並且在後台運行,通常用於某些服務程序、監控程序或者系統管理程序等。守護進程的…

    編程 2025-04-25
  • Python 進程通信

    當需要在不同進程之間進行通信時,Python 提供了幾種方法來實現進程間通信。這些方法包括隊列,管道,共享內存以及套接字。 1. 隊列 Python 隊列是進程安全的,並且可以很方…

    編程 2025-04-24
  • Linux下殺掉進程的命令詳解

    一、殺掉進程的概念 在進行Linux系統管理以及軟件開發過程中,我們常常需要殺掉卡死或異常程序的進程。殺掉進程是指在運行中的進程突然中斷或終止運行,也稱為進程終止。 殺掉進程的主要…

    編程 2025-04-24

發表回復

登錄後才能評論