simple-thread-pool 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README +22 -0
  2. data/lib/simple-thread-pool.rb +64 -0
  3. 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
+