不明な点が2つほどあります。
まずは、TLSを使うコードについてです。
#define _OPEN_THREADS #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<pthread.h> #define THREADS 3 __thread int tls; int global; void *func(void *arg){ int num = *(int *)arg; tls = num; global = num; sleep(1); printf("Thread = %d tls = %d global = %d\n", num, tls, global); } int main(){ int ret; pthread_t thread[THREADS]; int num; for(num = 0; num < THREADS; num++){ ret = pthread_create(&thread[num], NULL, func, (void *)&num); if(ret){ printf("Error pthread_create\n"); exit(1); } } for(num = 0; num < THREADS; num++){ ret = pthread_join(thread[num], NULL); if(ret){ printf("Error pthread_join\n"); exit(1); } } return 0; }
実行すると・・・毎回、全然違う値がランダムに出現します。
Thread = 0 tls = 0 global = 0 Thread = 1 tls = 1 global = 0 Thread = 2 tls = 2 global = 0 Thread = 2 tls = 2 global = 0 Thread = 0 tls = 0 global = 0 Thread = 2 tls = 2 global = 0 Thread = 2 tls = 2 global = 0 Thread = 2 tls = 2 global = 0 Thread = 0 tls = 0 global = 0
num の値はfor文によっt、0 ~ 2 まで増えていきます・・・
が、なんでこのような結果になるのでしょうか??
ランダムでは困ります。ちゃんと毎回同じような結果が出るようにするにはどうすればよろしいでしょうか??
2,スレッド実行のタイミング
#include<stdio.h> #include<stdlib.h> #include<pthread.h> #include<unistd.h> void *func(){ int pid; pthread_t thread_id; thread_id = pthread_self(); fprintf(stdout, "func called\n"); fprintf(stdout, " thread ID = %ld\n", thread_id); pid = getpid(); fprintf(stdout, " 2 : pid = %d\n", pid); } int main(){ pthread_t thread; int pid; fprintf(stdout, "----Program start----\n"); pid = getpid(); fprintf(stdout, "1 : pid = %d\n", pid); if(pthread_create(&thread, NULL, func, NULL) != 0) fprintf(stderr, "Failed to create thread"); printf("pthread_create called : thread ID = %ld\n\n", thread); pthread_join(thread, NULL); return 0; }
結果は以下のようになりました。
----Program start---- 1 : pid = 2740 pthread_create called : thread ID = 140101821789952 func called thread ID = 140101821789952 2 : pid = 2740
「ふ〜〜ん」って感じですが、
Pthreadプログラミング(1)
新しいスレッドを作成する
上記のサイトとは結果が異なります。
(1),プロセスとスレッドでPIDが違っている(私の方では、毎回同じです。)
(2),スレッドの関数の呼び出しタイミングが異なる。
古いサイトなので、(1)の方はおそらくカーネルのバージョンの違いだと思います。
(2)番のほうですね。
プロセススケジューリングはスレッド単位で行われます。
つまり、createされてからjoinされるまで、スレッドの実行タイミングはプログラマは把握できないということでしょうか?
[sched.c / sched.hなど]
inux-4.7.3/arch/powerpc/platforms/cell/spufs/sched.c linux-4.7.3/kernel/time/tick-sched.c linux-4.7.3/net/netfilter/ipvs/ip_vs_sched.c linux-4.7.3/net/sunrpc/sched.c linux-4.7.3/tools/perf/builtin-sched.c linux-4.7.3/tools/perf/tests/evsel-tp-sched.c linux-4.7.3/include/asm-generic/bitops/sched.h linux-4.7.3/include/linux/sched.h linux-4.7.3/include/linux/sunrpc/sched.h linux-4.7.3/include/net/pkt_sched.h linux-4.7.3/include/trace/events/sched.h linux-4.7.3/include/uapi/linux/pkt_sched.h linux-4.7.3/include/uapi/linux/sched.h linux-4.7.3/include/xen/interface/sched.h linux-4.7.3/kernel/sched/sched.h linux-4.7.3/kernel/time/tick-sched.h
スレッドの実行タイミングはスケジューラのアルゴリズムに任せられているわけですよね。
マルチスレッドなどをプログラムする時は、kernel側のスケジューリングアルゴリズムを把握し、スレッドが呼び出されるタイミングを工夫しないといけないということでしょうか??
(どんてもなく大変ですね・・・)
どなたか教えてください。
環境 : Linux Debian系 64bit gcc です。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/28 04:01 編集
2017/07/28 07:20 編集
2017/07/28 07:51
2017/07/29 11:42
2017/07/29 14:21