simple-thread-pool 0.0.1
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.
- data/README +22 -0
- data/lib/simple-thread-pool.rb +64 -0
- metadata +63 -0
data/README
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Thread Pool is meant to be an easy to use implementation of a fairly naive thread pool. For example, here's some code that will download 100 google search queries in parallel.
|
2
|
+
|
3
|
+
require 'open-uri'
|
4
|
+
require 'thread-pool'
|
5
|
+
|
6
|
+
number_of_files = 100
|
7
|
+
number_of_files.times do |i|
|
8
|
+
ThreadPool.give_work("http://www.google.com/search?q=#{i}",i) do |url,index|
|
9
|
+
data = open(url).read
|
10
|
+
f = File.new("google-#{i}",'w')
|
11
|
+
f.puts(data)
|
12
|
+
f.close
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ThreadPool.start_up(number_of_files)
|
17
|
+
|
18
|
+
while ThreadPool.num_executing > 0 or ThreadPool.queue_size > 0
|
19
|
+
sleep(1)
|
20
|
+
end
|
21
|
+
|
22
|
+
This approach of course has its limitations, and it's important to follow best practices with respect to share resources etc..., but it does make it very easy to distribute heavily I/O bound task across a number of non-blocking processes.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class SimpleThreadPool
|
2
|
+
class << self
|
3
|
+
def start_up(thread_count)
|
4
|
+
@thread_work_queues = {}
|
5
|
+
@locks = {}
|
6
|
+
@threads = []
|
7
|
+
@current_jobs = {}
|
8
|
+
thread_count.times do |i|
|
9
|
+
@thread_work_queues[i] = []
|
10
|
+
@locks[i] = Mutex.new
|
11
|
+
@threads << Thread.new(i,@thread_work_queues[i],@locks[i],@current_jobs) do |index,queue,lock,executing_jobs|
|
12
|
+
|
13
|
+
while true
|
14
|
+
if queue.size > 0
|
15
|
+
#do the mutex
|
16
|
+
job = nil
|
17
|
+
lock.synchronize {
|
18
|
+
job = queue.slice!(0)
|
19
|
+
}
|
20
|
+
if job
|
21
|
+
executing_jobs[index] = job
|
22
|
+
job[:block].call(job[:args])
|
23
|
+
executing_jobs.delete(index)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
#keep looking for work until the parent pid dies
|
28
|
+
#puts "Worker-#{index} out of stuff to do"
|
29
|
+
sleep(0.1)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def give_work( *args,&block)
|
37
|
+
min = -1
|
38
|
+
min_key = nil
|
39
|
+
@thread_work_queues.each_pair do |k,v|
|
40
|
+
if min_key == nil or v.size < min
|
41
|
+
min = v.size
|
42
|
+
min_key = k
|
43
|
+
end
|
44
|
+
end
|
45
|
+
@thread_work_queues[min_key]
|
46
|
+
@locks[min_key].synchronize {
|
47
|
+
@thread_work_queues[min_key] << {:block => block, :args => args}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def queue_size
|
52
|
+
size = 0
|
53
|
+
@thread_work_queues.each_pair do |k,v|
|
54
|
+
size += v.size
|
55
|
+
end
|
56
|
+
size
|
57
|
+
end
|
58
|
+
|
59
|
+
def num_executing
|
60
|
+
@current_jobs.keys.inject(0){|a,b| @current_jobs[b] ? a+ 1 : a }
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple-thread-pool
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Evan Dowling
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-06-02 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description:
|
22
|
+
email: dowling.evan@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README
|
29
|
+
files:
|
30
|
+
- lib/simple-thread-pool.rb
|
31
|
+
- README
|
32
|
+
has_rdoc: true
|
33
|
+
homepage: http://github.com/evandowling
|
34
|
+
licenses: []
|
35
|
+
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.3.6
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: A gem to package thread pools in an easy to use way
|
62
|
+
test_files: []
|
63
|
+
|