質問するログイン新規登録

回答編集履歴

4

一段落、コメントから追記

2017/07/29 22:00

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -12,6 +12,9 @@
12
12
  2番目にcreateしたスレッド、即ち num == 1を渡したつもりのスレッドが、
13
13
  いざ動き出し```num = *(int*)arg;```と**アクセスした時は、既にmain()側の for 文によってnumの値が2になった後**だった、よって tls 変数にも2が代入されてしまった。残念!
14
14
 
15
+ 一段落を追記。
16
+ 3つのスレッドは0→1→2→3というnumの変化に同期して生成されるが、同期してるのはあくまで「スケジューリング対象にする」作業でしかない。実際にfunc()が動くタイミングはスケジューラに任されるので、いつ動くか、それは予想がつかないことなのだ。よって0→1→2→3というnumの変化とfunc()の動作は同期しない。
17
+
15
18
  main()側は、各スレッドに渡すパラメータを、それぞれ異なるメモリに格納して渡せば良いだろう。例えばこんな風に。
16
19
  ```C
17
20
  int args[THREADS]; //

3

微修正

2017/07/29 22:00

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -22,7 +22,7 @@
22
22
  ```
23
23
  これで3つのスレッドに、0, 1, 2と異なる値を渡せるのではないか。
24
24
 
25
- 念の為1:int global変数はTLS(Thread Local Storage)ではないので、実体は一個の変数である。3つのスレッドが```global = num;``` する都度、値は上書きされる。
25
+ 念の為1:int global変数はTLS(Thread Local Storageと言うのかw)ではない、実体は一個の変数である。3つのスレッドが```global = num;``` する都度、値は上書きされる。
26
26
  その直後、各スレッドは```sleep(1);``` している。眠りから覚めた3つのスレッドが```printf(" ・・・global = %d\n", ・・・ global);```で表示するのは、スリープする直前、**最後に上書きした値**と思われる。
27
27
 
28
28
  念の為2:create直後も、スリープから目覚めた後も、3つのスレッドがどういう順序で動き出すかは、運を天にまかせるべきことじゃないかな。

2

引数をパラメータに変更

2017/07/27 15:53

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -3,7 +3,7 @@
3
3
  > num の値はfor文によっt、0 ~ 2 まで増えていきます・・・
4
4
  > が、なんでこのような結果になるのでしょうか??
5
5
 
6
- 各スレッドに渡す引数を、こう安易に渡したのが不具合の原因だろう。
6
+ 各スレッドに渡すパラメータを、こう安易に渡したのが不具合の原因だろう。
7
7
  ```C
8
8
  for (num = 0; num < THREADS; num++) {
9
9
  ret = pthread_create(・・・, (void *)&num);
@@ -12,7 +12,7 @@
12
12
  2番目にcreateしたスレッド、即ち num == 1を渡したつもりのスレッドが、
13
13
  いざ動き出し```num = *(int*)arg;```と**アクセスした時は、既にmain()側の for 文によってnumの値が2になった後**だった、よって tls 変数にも2が代入されてしまった。残念!
14
14
 
15
- main()側は、各スレッドに渡す引数を、それぞれ異なるメモリに格納して渡せば良いだろう。例えばこんな風に。
15
+ main()側は、各スレッドに渡すパラメータを、それぞれ異なるメモリに格納して渡せば良いだろう。例えばこんな風に。
16
16
  ```C
17
17
  int args[THREADS]; //
18
18
 
@@ -23,6 +23,6 @@
23
23
  これで3つのスレッドに、0, 1, 2と異なる値を渡せるのではないか。
24
24
 
25
25
  念の為1:int global変数はTLS(Thread Local Storage)ではないので、実体は一個の変数である。3つのスレッドが```global = num;``` する都度、値は上書きされる。
26
- その直後、各スレッドは```sleep(1);``` る。眠りから覚めた3つのスレッドが```printf(" ・・・global = %d\n", ・・・ global);```で表示するのは、スリープする直前、**最後に上書きした値**と思われる。
26
+ その直後、各スレッドは```sleep(1);``` している。眠りから覚めた3つのスレッドが```printf(" ・・・global = %d\n", ・・・ global);```で表示するのは、スリープする直前、**最後に上書きした値**と思われる。
27
27
 
28
28
  念の為2:create直後も、スリープから目覚めた後も、3つのスレッドがどういう順序で動き出すかは、運を天にまかせるべきことじゃないかな。

1

スペルミスを修正

2017/07/27 15:48

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -22,7 +22,7 @@
22
22
  ```
23
23
  これで3つのスレッドに、0, 1, 2と異なる値を渡せるのではないか。
24
24
 
25
- 念の為1:int global変数はTLS(Thread Loval Storage)ではないので、実体は一個の変数である。3つのスレッドが```global = num;``` する都度、値は上書きされる。
25
+ 念の為1:int global変数はTLS(Thread Local Storage)ではないので、実体は一個の変数である。3つのスレッドが```global = num;``` する都度、値は上書きされる。
26
26
  その直後、各スレッドは```sleep(1);``` する。眠りから覚めた3つのスレッドが```printf(" ・・・global = %d\n", ・・・ global);```で表示するのは、スリープする直前、**最後に上書きした値**と思われる。
27
27
 
28
28
  念の為2:create直後も、スリープから目覚めた後も、3つのスレッドがどういう順序で動き出すかは、運を天にまかせるべきことじゃないかな。