回答編集履歴

5

markup code tag

2016/09/29 04:38

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -64,7 +64,7 @@
64
64
 
65
65
 
66
66
 
67
- ```
67
+ ```python
68
68
 
69
69
  from threading import Thread, Semaphore
70
70
 

4

refine

2016/09/29 04:38

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -5,10 +5,6 @@
5
5
  ----
6
6
 
7
7
  **追記:** 「スレッド処理が完了するまで」を排他制御したい場合、下記のような実装方法があり得ます。`tokens`キューに"実行許可トークン"を2つ入れておき、各スレッドの処理開始直前で同トークンを取得、終了時にトークンを返却することで、同時に発行されるトークン数=並列実行数を制限することができます。また、トークン返却(`tq.put(token)`)は確実に行わないと並列実行数が減少(0になればデッドロック)してしまうので、try~finallyで囲ってあります。
8
-
9
-
10
-
11
- `tokens`キューによる効果はセマフォ([threading.Semaphore](http://docs.python.jp/3/library/threading.html#semaphore-objects))そのものなので、セマフォを用いて実装する方法もあります。
12
8
 
13
9
 
14
10
 
@@ -60,6 +56,52 @@
60
56
 
61
57
  queue.put(i)
62
58
 
59
+ ```
60
+
61
+
62
+
63
+ `tokens`キューによる効果はセマフォ([threading.Semaphore](http://docs.python.jp/3/library/threading.html#semaphore-objects))動作そのものなので、セマフォを用いて実装する方法もあります。セマフォ版の方がシンプルかと思います。
64
+
63
65
 
64
66
 
65
67
  ```
68
+
69
+ from threading import Thread, Semaphore
70
+
71
+ from queue import Queue
72
+
73
+ import time
74
+
75
+
76
+
77
+ queue = Queue()
78
+
79
+ sem = Semaphore(2)
80
+
81
+
82
+
83
+ def main(sem, q):
84
+
85
+ i = q.get()
86
+
87
+ with sem:
88
+
89
+ print('スレッド ' + str(i) + ' 開始')
90
+
91
+ time.sleep(i)
92
+
93
+ print('スレッド ' + str(i) + ' 終了')
94
+
95
+
96
+
97
+ if __name__ == '__main__':
98
+
99
+ for i in 10, 5, 2:
100
+
101
+ th = Thread(target=main, args=(sem, queue))
102
+
103
+ th.start()
104
+
105
+ queue.put(i)
106
+
107
+ ```

3

refine

2016/09/29 04:37

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -5,6 +5,10 @@
5
5
  ----
6
6
 
7
7
  **追記:** 「スレッド処理が完了するまで」を排他制御したい場合、下記のような実装方法があり得ます。`tokens`キューに"実行許可トークン"を2つ入れておき、各スレッドの処理開始直前で同トークンを取得、終了時にトークンを返却することで、同時に発行されるトークン数=並列実行数を制限することができます。また、トークン返却(`tq.put(token)`)は確実に行わないと並列実行数が減少(0になればデッドロック)してしまうので、try~finallyで囲ってあります。
8
+
9
+
10
+
11
+ `tokens`キューによる効果はセマフォ([threading.Semaphore](http://docs.python.jp/3/library/threading.html#semaphore-objects))そのものなので、セマフォを用いて実装する方法もあります。
8
12
 
9
13
 
10
14
 

2

refine

2016/09/29 04:34

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ----
6
6
 
7
- **追記:** 「スレッド処理が完了するまで」を排他制御したい場合、下記のような実装方法があり得ます。`tokens`キューに"実行許可トークン"を2つ入れておき、各スレッドの処理開始直前で同トークンを取得、終了時にトークンを返却することで、同時に発行されるトークン数=並列実行数を制限することができます。
7
+ **追記:** 「スレッド処理が完了するまで」を排他制御したい場合、下記のような実装方法があり得ます。`tokens`キューに"実行許可トークン"を2つ入れておき、各スレッドの処理開始直前で同トークンを取得、終了時にトークンを返却することで、同時に発行されるトークン数=並列実行数を制限することができます。また、トークン返却(`tq.put(token)`)は確実に行わないと並列実行数が減少(0になればデッドロック)してしまうので、try~finallyで囲ってあります。
8
8
 
9
9
 
10
10
 
@@ -30,13 +30,17 @@
30
30
 
31
31
  token = tq.get() # get token
32
32
 
33
- print('スレッド ' + str(i) + ' 開始')
33
+ try:
34
34
 
35
- time.sleep(i)
35
+ print('スレッド ' + str(i) + ' 開始')
36
36
 
37
- print('スレッド ' + str(i) + ' 終了')
37
+ time.sleep(i)
38
38
 
39
+ print('スレッド ' + str(i) + ' 終了')
40
+
41
+ finally:
42
+
39
- tq.put(token) # return token
43
+ tq.put(token) # return token
40
44
 
41
45
 
42
46
 

1

update

2016/09/29 04:31

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -1 +1,57 @@
1
1
  [queue.Queue](http://docs.python.jp/3/library/queue.html)クラスのコンストラクタに最大容量`maxsize`を指定できます。キューが一杯の間はput操作がブロックされ、get操作によりキューに空きが出来ると処理が進むようになります。
2
+
3
+
4
+
5
+ ----
6
+
7
+ **追記:** 「スレッド処理が完了するまで」を排他制御したい場合、下記のような実装方法があり得ます。`tokens`キューに"実行許可トークン"を2つ入れておき、各スレッドの処理開始直前で同トークンを取得、終了時にトークンを返却することで、同時に発行されるトークン数=並列実行数を制限することができます。
8
+
9
+
10
+
11
+ ```python
12
+
13
+ from threading import Thread, active_count
14
+
15
+ from queue import Queue
16
+
17
+ import time
18
+
19
+
20
+
21
+ queue = Queue()
22
+
23
+ tokens = Queue()
24
+
25
+
26
+
27
+ def main(tq, q):
28
+
29
+ i = q.get()
30
+
31
+ token = tq.get() # get token
32
+
33
+ print('スレッド ' + str(i) + ' 開始')
34
+
35
+ time.sleep(i)
36
+
37
+ print('スレッド ' + str(i) + ' 終了')
38
+
39
+ tq.put(token) # return token
40
+
41
+
42
+
43
+ if __name__ == '__main__':
44
+
45
+ [tokens.put(x) for x in range(2)]
46
+
47
+ for i in 10, 5, 2:
48
+
49
+ th = Thread(target=main, args=(tokens, queue))
50
+
51
+ th.start()
52
+
53
+ queue.put(i)
54
+
55
+
56
+
57
+ ```