ready_pool 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/lib/ready_pool.rb +131 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OGE3MTVjNThkYTQxM2U3ZGE1ODg4OWU2ODUyMWNiZDNjYzk1ZWJhYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MDQ4OWJkOTQyZjVhOTZmOGNiMmQ5OGNjYjdjYmVmYmUyYjhmZjk0NQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ODM0ODIxZjEzYTkzYmJjMDAzMzNlZWY5N2YzYTI3YjBjYTI2OGUzYTU5OTVj
|
10
|
+
ZjJkNWI0ZDFlYzk2ZTk0ODA3NDk2N2NhNDIzZTE1ZTgzZDIxMjVhNTkwZDll
|
11
|
+
M2ZjMWRmMGViNzZiZmE0OTYxMjEyY2U2YzFkMTQ2NTZlZGE4NzI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Y2U0ODdlYzcyNGU4ZWVhODU5ZTkxNDRmNWJlMTAzNzRmMWM5NDgzOWM3Y2Q1
|
14
|
+
NTk5ZTZmOThlNzliNWZjZDVkMTczYTJhNzY3ZTk0MjNkMmQ5ODUwYjUwMjhm
|
15
|
+
MDc0YmUxNWQyNGExYWRkNDljZTk3NjgwZWY2MDBlZGY5OTg1ZGY=
|
data/lib/ready_pool.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
########################################################################
|
4
|
+
# thread pool implementation
|
5
|
+
#
|
6
|
+
# In the example 10 threads are prepared to run the Proc passed as the
|
7
|
+
# second argument. If more are needed they are spun up when required.
|
8
|
+
# When a thread completes its task it returns itself to the pool.
|
9
|
+
#
|
10
|
+
# The start method passes its argument to the thread Proc.
|
11
|
+
#
|
12
|
+
# ==Example
|
13
|
+
#
|
14
|
+
# require 'ready_pool'
|
15
|
+
# require 'async_emitter'
|
16
|
+
#
|
17
|
+
# emitter = AsyncEmitter.new
|
18
|
+
#
|
19
|
+
# emitter.on :data, lambda { |data| puts "emitted #{data}" }
|
20
|
+
#
|
21
|
+
# rp = ReadyPool.new 10, Proc.new { |data| emitter.emit :data, data }
|
22
|
+
#
|
23
|
+
# 20.times do |i|
|
24
|
+
# rp.start i
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# gets #wait for user input
|
28
|
+
#
|
29
|
+
# rp.kill_all
|
30
|
+
#
|
31
|
+
########################################################################
|
32
|
+
|
33
|
+
class ReadyPool
|
34
|
+
|
35
|
+
################################################################
|
36
|
+
# ReadyPool constructor
|
37
|
+
#
|
38
|
+
# @param num_threads [FixedNum] initial number of threads
|
39
|
+
# @param procedure [Proc] called when start method is called
|
40
|
+
################################################################
|
41
|
+
def initialize (num_threads, procedure)
|
42
|
+
@procedure = procedure
|
43
|
+
@pool_semaphore = Mutex.new
|
44
|
+
@pool_condition = ConditionVariable.new
|
45
|
+
@pool = []
|
46
|
+
|
47
|
+
@pool_semaphore.synchronize do
|
48
|
+
num_threads.times do |i|
|
49
|
+
@pool[i] = new_thread
|
50
|
+
@pool[i][:ready] = false
|
51
|
+
|
52
|
+
@pool[i][:thread] = Thread.new do
|
53
|
+
thread_proc @pool[i]
|
54
|
+
end
|
55
|
+
|
56
|
+
@pool_condition.wait @pool_semaphore
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
################################################################
|
63
|
+
# starts the thread
|
64
|
+
#
|
65
|
+
# @param data [Object] data passed to the thread Proc
|
66
|
+
################################################################
|
67
|
+
def start data
|
68
|
+
th = nil
|
69
|
+
@pool_semaphore.synchronize do
|
70
|
+
th = @pool.shift
|
71
|
+
end
|
72
|
+
|
73
|
+
if th == nil
|
74
|
+
th = new_thread
|
75
|
+
th[:ready] = false
|
76
|
+
th[:thread] = Thread.new do
|
77
|
+
thread_proc th
|
78
|
+
end
|
79
|
+
|
80
|
+
@pool_semaphore.synchronize do
|
81
|
+
@pool_condition.wait @pool_semaphore
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
th[:data] = data
|
86
|
+
signal_thread th
|
87
|
+
end
|
88
|
+
|
89
|
+
################################################################
|
90
|
+
# kills all threads
|
91
|
+
################################################################
|
92
|
+
def kill_all
|
93
|
+
@pool.each do |th|
|
94
|
+
Thread.kill th[:thread]
|
95
|
+
end
|
96
|
+
@pool = []
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
def thread_proc (th)
|
101
|
+
while true
|
102
|
+
th[:semaphore].synchronize do
|
103
|
+
|
104
|
+
@pool_semaphore.synchronize do
|
105
|
+
@pool_condition.signal
|
106
|
+
end
|
107
|
+
|
108
|
+
th[:cv].wait th[:semaphore]
|
109
|
+
@procedure.call th[:data]
|
110
|
+
@pool_semaphore.synchronize do
|
111
|
+
@pool.push th
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def new_thread
|
119
|
+
th = {}
|
120
|
+
th[:semaphore] = Mutex.new
|
121
|
+
th[:cv] = ConditionVariable.new
|
122
|
+
return th
|
123
|
+
end
|
124
|
+
|
125
|
+
def signal_thread (th)
|
126
|
+
th[:semaphore].synchronize do
|
127
|
+
th[:cv].signal
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ready_pool
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Greg Martin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-27 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A thread pool implementation for ruby
|
14
|
+
email: greg@softsprocket.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/ready_pool.rb
|
20
|
+
homepage: http://rubygems.org/gems/ready_pool.rb
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubyforge_project:
|
40
|
+
rubygems_version: 2.4.6
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: ReadyPool
|
44
|
+
test_files: []
|
45
|
+
has_rdoc:
|