簡體   English   中英

用叉子子進程

[英]Child processes with fork

我正在嘗試制作一個簡單的C程序,該程序將調用fork方法三次,並顯示子進程的標識符(UID,GID,PID,PPID,PGID)。 而且,我正在努力正確理解實際發生的事情。 在我的代碼中,我為方法fork()和顯示標識符使用了單獨的方法,並且對於父進程,我試圖使用waitpid方法來等待所有子進程死亡。 現在,我真的很困惑,因為我無法以明確表示它可以正常工作的方式使其工作。 您能給我任何建議或顯示解決我問題的更好方法嗎?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void identifiers();
void forkMethod();

int main(void)
{ 
    forkMethod();
    return 0;
}

void forkMethod()
{
    int k;
    int status;
    for (k=0;k<3;k++){
        switch (fork()) {
        case -1:
            perror("fork error");
            exit(EXIT_FAILURE);
            break;
        case 0:         
            identifiers();  
            break;
        default:
            //wait(&status);
            waitpid(getpid(), &status, WNOHANG);
            sleep(1);
            break;
        }
    }
}

void identifiers()
{
    pid_t pid = getpid();
    pid_t ppid = getppid();
    pid_t pgid = getpgid(pid);
    pid_t uid = getuid();
    pid_t gid = getgid();
    printf("UID:%d GID:%d PID:%d PPID:%d PGID:%d\n", uid, gid, pid, ppid, pgid);
}

// ================================================ ===========

首先,謝謝大家的回答,並指出我犯的所有這些錯誤,

我知道代碼很可怕,可能仍然有一些問題,但是現在我想我已經想要了。

正如@John Bollinger所問,我的列表中有什么主要功能:1.編寫一個顯示指定進程的標識符UID,GUID,PID,PPID,PGID的函數2.調用fork()函數3次,並為子進程顯示這些標識符3.使用sleep功能從最舊的順序開始顯示進程。4.根據結果顯示進程樹。

謝謝@juhist和@Jonathan Leffler的簡單明了的解釋。 如果代碼中有任何重大問題,請發布

並且知道最終的代碼是:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void identifiers(); // function that display identifiers
void forkMethod(); // function that calls fork() function 3 times
void tree(int); // function displaying processes tree

int main(void)
{ 
identifiers(); // displaying ID's for parent process
printf("Parent pid: %d\n", getpid());   
printf("Child processes: \n");      

forkMethod();   

return 0;
}

void forkMethod()
{
int k;
int status;
int pid;

for (k=0;k<3;k++){
pid = fork();
    switch (pid) {
    case -1:
        perror("fork error");
        exit(EXIT_FAILURE);
        break;
    case 0: 
    identifiers(); 
    exit(0);             
    default:           
    tree(getpid());            
    wait(&status); 
        sleep(1);   
    break;
    }
}
}

void identifiers()
{
pid_t pid = getpid();
pid_t ppid = getppid();
pid_t pgid = getpgid(pid);
pid_t uid = getuid();
pid_t gid = getgid();
printf("\nUID:%d GID:%d PID:%d PPID:%d PGID:%d\n", uid, gid, pid, ppid, pgid);
}

void tree(int pid)
{
char pstree[] = "pstree -np "; 
char cmd[12];
sprintf(cmd, "%s%d", pstree, pid);
system(cmd);
}           

您的問題之一是此代碼中:

case 0:         
    identifiers();  
    break;

當然,您打算這樣做:

case 0:
    identifiers();
    exit(0);

否則,子進程將繼續執行,並且您將獲得太多的派生。

另一個問題是您正在使用父pid(而不是子pid)調用waitpid()。 在使用WNOHANG參數時,調用沒有任何用處。 使用wait()或將fork所返回的孩子的pid存儲在某個地方,並將該pid用作waitpid()的參數。

此外,您應該考慮檢查waitpid()的返回值。 在較大的程序中,如果您有信號處理程序,則調用可能會被信號中斷並返回錯誤代碼,錯誤代碼為errno == EINTR。 最好重試被信號中斷的系統調用,並檢查其他可能的錯誤返回。

在這行上:

waitpid(getpid(), &status, WNOHANG);

getpid()將始終獲取父pid,而不是子pid。 建議將switch(fork())更改為

pid= fork(); switch(pid) { ... }

waitpid行到

waitpid(pid, &status, 0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM