2013-04-07 3 views
5

clone()を使用して新しいスレッドを作成しようとしています。次のコード(...)では:Linux上でclone()を使って実際のスレッドを作成する方法は?

#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; 
} 

私は、次を得る:

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... 

だから、要するに、私のプログラムは何をするのでしょうか? cloneで新しいスレッドを作成し、そのステータスを見ることができるように/proc/self/statusを表示します。私のスレッドは1秒間スリープしているので、/proc/self/statusが印刷されてもまだ生きています。

しかし、私のスレッドを共通のスレッドのように振る舞わないようにする少なくとも2つのことがあります。まず、上記のように、プロセスのpidは10839で、スレッドのpidは10840です。したがって、プロセスとスレッドは共通のスレッドで発生するのと同じpidを持ちません。第二に、私のスレッドが作成された後でさえ、私のプロセス '/proc/self/statusファイルのThreads:フィールドはまだ1です。したがって、私のスレッドはスレッドとして認識されないようです。

私の質問には、私のコードには何が欠けていますか?私のスレッドを共通のスレッドのように振る舞わせるにはどうすればいいですか? cloneの3番目の引数に欠けているオプションはありますか?

答えて

6

フラグCLONE_THREADを参照すると、新しいスレッドが呼び出しプロセスと同じスレッドグループに配置されます。

CLONE_THREADを指定すると、新しいスレッドは呼び出しプロセスと同じpidとppidを持つようになります。 posixスレッドで使用されます。以下は私のシステムからの出力です。

[anukalp @:LWP列は現在、軽量のプロセスであり、異なる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 

はまた、/ procの/自己/ステータス変更の出力は、私はprintfをのカップルを追加したしたことがあると言います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 

これが役立つかどうかお知らせください。

+0

はい、多くの助けになりました。ありがとうございました!そして、ところで、どのようにして最初の出力(LWP列を持つ出力)を得ましたか? – LuisABOL

+0

それは助けを聞いてうれしい!最初の出力のコマンド:ps -eLF – anukalp