2013-04-07 8 views
5

Próbuję utworzyć nowy wątek przy użyciu clone(). Z następującego kodu (...):Jak stworzyć prawdziwy wątek z clone() w systemie Linux?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define _SCHED_H 1 
#define __USE_GNU 1 
#include <bits/sched.h> 

#define STACK_SIZE 4096 

int func(void *arg) { 
    printf("Inside func.\n"); 
    sleep(1); 
    printf("Terminating func...\n"); 

    return 0; 
} 

int main() { 
    printf("This process pid: %u\n", getpid()); 
    char status_file[] = "/proc/self/status"; 
    void *child_stack = malloc(STACK_SIZE); 
    int thread_pid; 

    printf("Creating new thread...\n"); 
    thread_pid = clone(&func, child_stack+STACK_SIZE, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES, NULL); 
    printf("Done! Thread pid: %d\n", thread_pid); 

    FILE *fp = fopen(status_file, "rb"); 

    printf("Looking into %s...\n", status_file); 

    while(1) { 
     char ch = fgetc(fp); 
     if(feof(fp)) break; 
     printf("%c", ch); 
    } 

    fclose(fp); 

    getchar(); 

    return 0; 
} 

uzyskać następujące:

This process pid: 10839 
Creating new thread... 
Done! Thread pid: 10840 
Inside func. 
Looking into /proc/self/status... 
Name: threadTest02 
State: R (running) 
Tgid: 10839 
Pid: 10839 
PPid: 4777 
TracerPid:  0 
Uid: 1000 1000 1000 1000 
Gid: 1000 1000 1000 1000 
FDSize: 256 
Groups: 4 20 24 27 30 46 107 123 124 1000 
VmPeak:  4300 kB 
VmSize:  4300 kB 
VmLck:   0 kB 
VmPin:   0 kB 
VmHWM:  356 kB 
VmRSS:  356 kB 
VmData:  188 kB 
VmStk:  136 kB 
VmExe:   4 kB 
VmLib:  1884 kB 
VmPTE:  32 kB 
VmSwap:  0 kB 
Threads:  1 
SigQ: 0/22869 
SigPnd: 0000000000000000 
ShdPnd: 0000000000000000 
SigBlk: 0000000000000000 
SigIgn: 0000000000000000 
SigCgt: 0000000000000000 
CapInh: 0000000000000000 
CapPrm: 0000000000000000 
CapEff: 0000000000000000 
CapBnd: ffffffffffffffff 
Cpus_allowed: 3 
Cpus_allowed_list:  0-1 
Mems_allowed: 00000000,00000001 
Mems_allowed_list:  0 
voluntary_ctxt_switches:  1 
nonvoluntary_ctxt_switches:  1 
Terminating func... 

Tak, w skrócie, co robi mój program zrobić? Tworzy nowy wątek z clone i wyświetla jego /proc/self/status, dzięki czemu mogę zobaczyć jego status. Ponieważ mój wątek śpi przez 1 sekundę, wciąż jest żywy po wydrukowaniu /proc/self/status.

Istnieją jednak co najmniej dwie rzeczy, które sprawiają, że moja nić nie zachowuje się jak zwykły wątek. Po pierwsze, jak można zobaczyć powyżej, proces "pid to 10839, a pid mojego wątku to 10840. Tak więc proces i mój wątek nie mają tego samego pid, jak ma to miejsce we wspólnym wątku. Po drugie, nawet po utworzeniu wątku pole Threads: pliku mojego procesu "/proc/self/status to nadal 1. Tak więc, mój wątek nie jest rozpoznawany jako wątek.

Moje pytanie brzmi: czego brakuje w moim kodzie? Co muszę zrobić, aby mój wątek zachowywał się jak zwykły wątek? Czy w trzecim argumencie clone brakuje jakiejś opcji?

Odpowiedz

6

Możesz chcieć zobaczyć flagę CLONE_THREAD, która umieści nowy wątek w tej samej grupie wątków, co proces wywołujący.

Po nadaniu CLONE_THREAD nowy wątek będzie miał ten sam pid i ppid co proces wywołujący. Jest używany w wątkach posix. Poniżej znajduje się dane wyjściowe z mojego systemu. kolumna LWP mówi, że to jest teraz proces lekki i ma inny TID

UID  PID PPID LWP C NLWP SZ RSS PSR STIME TTY   TIME CMD 
anukalp 18398 9638 18398 0 2 464 456 0 10:56 pts/3 00:00:00 ./a.out 
anukalp 18398 9638 18399 0 2 464 456 1 10:56 pts/3 00:00:00 ./a.out 

również wyjście zmian/proc/self/status, dodałem kilka printfs:

[anukalp @ localhost ~] $ ./a.out

This process pid: 18398 
Creating new thread... 
Done! Thread pid: 18399 /* This is now thread id, available to caller of clone */ 
getpid(): ad pid: 18399 
Inside func. 
getpid(): 18398 
getppid(): 9638 
Looking into /proc/self/status... 
Name: a.out 
State: R (running) 
Tgid: 18398 
Pid: 18398 
PPid: 9638 
TracerPid:  0 
Uid: 500  500  500  500 
Gid: 500  500  500  500 
FDSize: 256 
Groups: 7 19 22 80 81 82 83 100 490 500 
VmPeak:  1856 kB 
VmSize:  1856 kB 
VmLck:   0 kB 
VmPin:   0 kB 
VmHWM:  248 kB 
VmRSS:  248 kB 
VmData:  168 kB 
VmStk:  140 kB 
VmExe:   4 kB 
VmLib:  1516 kB 
VmPTE:  16 kB 
VmSwap:  0 kB 
Threads:  2 
SigQ: 1/14050 
SigPnd: 0000000000000000 
ShdPnd: 0000000000000000 
SigBlk: 0000000000000000 
SigIgn: 0000000000000000 
SigCgt: 0000000000000000 
CapInh: 0000000000000000 
CapPrm: 0000000000000000 
CapEff: 0000000000000000 
CapBnd: ffffffffffffffff 
Cpus_allowed: 00000000,000000ff 
Cpus_allowed_list:  0-7 
voluntary_ctxt_switches:  1 
nonvoluntary_ctxt_switches:  0 
Inside thread: thread pid = 18398 
Inside thread: thread ppid = 9638 

Proszę dać mi znać, jeśli to pomoże!

+0

Tak, bardzo mi to pomogło! Dziękuję Ci! A tak nawiasem mówiąc, w jaki sposób otrzymałeś pierwsze wyjście (ten z kolumną LWP)? – LuisABOL

+0

Miło słyszeć, że pomogło! Polecenie dla pierwszego wyjścia: ps -eLF – anukalp

Powiązane problemy