2012-11-19 8 views
14

Ich möchte Kopien eines Prozesses erstellen mit fork() in C. Ich kann nicht herausfinden, wie Argumente an die Kopien meines Prozesses übergeben. Zum Beispiel möchte ich eine Ganzzahl an die Prozesskopien übergeben.Wie übergeben Sie Argumente an Prozesse erstellt von fork()

Oder ich was zu tun ist, wenn ich eine Schleife haben, in dem ich Gabel() aufrufen und wollen einen eindeutigen Wert auf Prozesse zu übergeben (zB 0 ... N)

for (int i = 0; i < 4; ++i) { 
    fork(); 
    // pass a unique value to new processes. 
} 
+2

'fork' erstellt eine Kopie eines laufenden Prozesses, es initiiert * keinen Prozess. – Beta

+0

Lesen Sie http://advancedlinuxprogramming.com/ –

Antwort

15

Der nette Teil über fork() ist, dass jeder Prozess automatisch laichen eine Kopie von allem bekommt der Elternteil hat, so zum Beispiel, lassen Sie uns sagen, dass wir einen int myvar zu jedem von zwei untergeordneten Prozesse übergeben wollen, aber ich möchte, dass jeder einen anderen Wert aus dem übergeordneten Prozess haben:

int main() 
{ 
    int myvar = 0; 
    if(fork()) 
     myvar = 1; 
    else if(fork()) 
     myvar = 2; 
    else 
     myvar = 3; 

    printf("I'm %d: myvar is %d\n", getpid(), myvar); 
    return 0; 
} 

So tut dies jeder Prozess ermöglicht eine „Kopie“ von myvar zu haben mit seinem eigenen Wert.

I'm 8517: myvar is 1 
I'm 8518: myvar is 2 
I'm 8521: myvar is 3 

Wenn Sie den Wert nicht geändert haben, hat jeder fork'd-Prozess denselben Wert.

+0

danke Mike. Du hast den Nagel auf den Kopf getroffen –

1

Siehe exec() family von Funktionen.

EDIT: Wenn Sie versuchen, Kopien des gleichen Programms wie der Basisprozess zu initialisieren, einfach weiter Variablen verwenden, wie von duskwuff vorgeschlagen.

1

Sie können clone() (die tatsächlich von fork() selbst verwendet wird) verwenden. Damit können Sie einen arg an Ihre Eingabe-Funktion übergeben.

http://linux.die.net/man/2/clone

+3

Nein, bitte nicht. 'clone' ist ein komplexer, Linux-spezifischer Syscall, der sehr gute Linux-Kenntnisse erfordert und hauptsächlich den wenigen * implementierenden * Thread-Bibliotheken (à la pthread) der Gurus vorbehalten ist. Siehe auch 'futex (7)' man page. –

+0

@ BasileStarynkevitch: Genau. Verwenden Sie Clone nur dann, wenn Sie ein echtes Low-Level-Hacking durchführen - der einzige Punkt des Clones ist, dass Sie einige Dinge im Userspace ausführen können, die zuvor nur im Kernel-Bereich passieren konnten, wie zum Beispiel Thread-Implementierung. Es ist kein allgemeiner Syscall. – Linuxios

7

Lokale und globale Variablen sind von Natur aus über eine fork() erhalten, so gibt es keine Notwendigkeit, „Argumente übergeben“. Wenn Sie eine Funktion in dem gegabelten Prozess aufrufen, können Sie so etwas wie tun:

pid_t pid = fork(); 
if (pid == 0) { 
    funcToCallInChild(argument); 
    exit(0); 
} 
6

Ich bin zu spät, zu reagieren, aber hier ist, wie ich es tun:

const char *progname = "./yourProgName"; 
const char *argument1 = "arg1"; 
const char *argument2 = "arg2"; 

if (fork() == 0) 
{ 
    // We are the child process, so replace the process with a new executable. 
    execl(progname, progname, argument1, argument2, (char *)NULL); 
} 
// The parent process continues from here. 

Zuerst Sie fork() den Prozess, ein neues Verfahren zu schaffen. Es hat immer noch den gleichen Speicherplatz wie der alte. fork() gibt sowohl für die übergeordneten als auch für die untergeordneten Prozesse zurück. Wenn fork() null zurückgibt, sind Sie der untergeordnete Prozess. Der untergeordnete Prozess verwendet dann execl(), um den Prozessspeicher durch einen aus einer neuen Datei zu ersetzen.

Beachten Sie, dass progname zweimal execl() gegeben wird. Die erste ist, was execl() tatsächlich versuchen wird zu laufen, die zweite ist argv [0]. Sie müssen beide angeben, oder die Anzahl der Argumente wird um eins verringert. Progname muss alle erforderlichen Pfadinformationen enthalten, um das gewünschte ausführbare Image zu finden.

Ich gebe zwei Argumente in diesem Beispiel, aber Sie können so viele übergeben, wie Sie möchten. Es muss mit NULL beendet werden, und ich denke, Sie müssen es als (char *) wie ich es zeigen zu werfen.

Dieser Ansatz gibt Ihnen einen völlig unabhängigen Prozess mit Argumenten und einer eindeutigen PID. Es kann weiter ausgeführt werden, lange nachdem der Elternprozess beendet wurde, oder es kann vor dem Elternprozess beendet werden.

Verwandte Themen