multiprocessing 0.0.1 → 0.0.2
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 +7 -0
- data/.gitignore +3 -1
- data/.yardopts +4 -0
- data/README.ja.md +121 -0
- data/README.md +85 -91
- data/Rakefile +24 -1
- data/lib/multiprocessing.rb +41 -1
- data/lib/multiprocessing/conditionvariable.rb +82 -60
- data/lib/multiprocessing/externalobject.rb +5 -3
- data/lib/multiprocessing/mutex.rb +126 -96
- data/lib/multiprocessing/processerror.rb +5 -0
- data/lib/multiprocessing/queue.rb +95 -27
- data/lib/multiprocessing/semaphore.rb +78 -27
- data/lib/multiprocessing/version.rb +12 -1
- data/spec/multiprocessing/conditionvariable_spec.rb +206 -0
- data/spec/multiprocessing/mutex_spec.rb +468 -74
- data/spec/multiprocessing/queue_spec.rb +341 -97
- data/spec/multiprocessing/semaphore_spec.rb +136 -33
- data/spec/spec_helper.rb +15 -1
- metadata +11 -12
- data/lib/multiprocessing/process.rb +0 -43
- data/spec/multiprocessing/process_spec.rb +0 -51
@@ -1,56 +1,159 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
require 'timeout'
|
3
3
|
|
4
|
-
describe MultiProcessing::Semaphore, "initialized with
|
4
|
+
describe MultiProcessing::Semaphore, "initialized with 2" do
|
5
5
|
|
6
6
|
before do
|
7
|
-
@semaphore = MultiProcessing::Semaphore.new
|
7
|
+
@semaphore = MultiProcessing::Semaphore.new 2
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
@semaphore.lock.should === @semaphore
|
12
|
-
end
|
10
|
+
describe "#P" do
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
context "when resource is remaining" do
|
13
|
+
it "return itself" do
|
14
|
+
@semaphore.lock.should === @semaphore
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when resource is not remaining" do
|
18
19
|
|
20
|
+
before do
|
21
|
+
fork do
|
22
|
+
@semaphore.P
|
23
|
+
@semaphore.P
|
24
|
+
sleep 0.03
|
25
|
+
end
|
26
|
+
sleep 0.01
|
27
|
+
end
|
28
|
+
|
29
|
+
it "blocks" do
|
30
|
+
proc{ timeout(0.01){ @semaphore.P } }.should raise_error Timeout::Error
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
19
34
|
|
20
|
-
it "#count returns number of remaining resource" do
|
21
|
-
@semaphore.count.should == 1
|
22
|
-
@semaphore.P
|
23
|
-
@semaphore.count.should == 0
|
24
|
-
@semaphore.V
|
25
|
-
@semaphore.V
|
26
|
-
@semaphore.count.should == 2
|
27
35
|
end
|
28
36
|
|
29
|
-
|
30
|
-
|
31
|
-
|
37
|
+
describe "#V" do
|
38
|
+
|
39
|
+
it "#V returns itself" do
|
40
|
+
@semaphore.lock
|
41
|
+
@semaphore.unlock.should === @semaphore
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when a thread is waiting" do
|
45
|
+
|
46
|
+
before do
|
47
|
+
@pid = fork do
|
48
|
+
@semaphore.P
|
49
|
+
@semaphore.P
|
50
|
+
@semaphore.P # blocks
|
51
|
+
end
|
52
|
+
@detached_thread = Process.detach(@pid)
|
53
|
+
sleep 0.01
|
54
|
+
end
|
55
|
+
|
56
|
+
it "makes the other thread blocked restart" do
|
57
|
+
@semaphore.V
|
58
|
+
@detached_thread.join(1).should_not be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
after do
|
62
|
+
begin
|
63
|
+
Process.kill :TERM, @pid
|
64
|
+
rescue Errno::ESRCH
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
32
70
|
end
|
33
71
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
72
|
+
describe "#count" do
|
73
|
+
|
74
|
+
context "resource locked in same thread" do
|
75
|
+
it "returns number of remaining resource" do
|
76
|
+
@semaphore.count.should == 2
|
77
|
+
@semaphore.P
|
78
|
+
@semaphore.count.should == 1
|
79
|
+
@semaphore.P
|
80
|
+
@semaphore.count.should == 0
|
81
|
+
@semaphore.V
|
82
|
+
@semaphore.count.should == 1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "resource locked in another process" do
|
87
|
+
|
88
|
+
before do
|
89
|
+
@pid = fork do
|
90
|
+
sleep 0.02
|
91
|
+
@semaphore.P
|
92
|
+
sleep 0.02
|
93
|
+
@semaphore.P
|
94
|
+
sleep 0.02
|
95
|
+
@semaphore.V
|
96
|
+
end
|
97
|
+
sleep 0.01
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns number of remaining resource" do
|
101
|
+
@semaphore.count.should == 2
|
102
|
+
sleep 0.02
|
103
|
+
@semaphore.count.should == 1
|
104
|
+
sleep 0.02
|
105
|
+
@semaphore.count.should == 0
|
106
|
+
sleep 0.02
|
107
|
+
@semaphore.count.should == 1
|
108
|
+
end
|
109
|
+
|
110
|
+
after do
|
111
|
+
begin
|
112
|
+
Process.kill :TERM, @pid
|
113
|
+
rescue Errno::ESRCH
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
38
117
|
end
|
39
|
-
|
40
|
-
@semaphore.try_P.should be_false
|
118
|
+
|
41
119
|
end
|
42
120
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
121
|
+
describe "#try_P" do
|
122
|
+
|
123
|
+
context "when remaining resource" do
|
124
|
+
it "returns true" do
|
125
|
+
@semaphore.try_P.should be_true
|
126
|
+
@semaphore.count.should == 1
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "when not remaining resource" do
|
131
|
+
it "returns false" do
|
132
|
+
pid = fork do
|
133
|
+
@semaphore.P
|
134
|
+
@semaphore.P
|
135
|
+
end
|
136
|
+
sleep 0.03
|
137
|
+
@semaphore.try_P.should be_false
|
138
|
+
@semaphore.count.should == 0
|
139
|
+
end
|
48
140
|
end
|
49
|
-
tmp.should be_true
|
50
|
-
@semaphore.count.should == 1
|
51
141
|
end
|
52
|
-
|
53
142
|
|
143
|
+
describe "#synchronize" do
|
144
|
+
it "locks resource and yields and unlocks" do
|
145
|
+
tmp = nil
|
146
|
+
@semaphore.count.should == 2
|
147
|
+
@semaphore.synchronize do
|
148
|
+
@semaphore.count.should == 1
|
149
|
+
tmp = true
|
150
|
+
end
|
151
|
+
tmp.should be_true
|
152
|
+
@semaphore.count.should == 2
|
153
|
+
end
|
154
|
+
end
|
54
155
|
|
55
156
|
end
|
56
157
|
|
158
|
+
|
159
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'simplecov'
|
3
|
+
|
4
|
+
SimpleCov.start do
|
5
|
+
add_filter "spec/"
|
6
|
+
end
|
7
|
+
|
8
|
+
pid = Process.pid
|
9
|
+
SimpleCov.at_exit do
|
10
|
+
SimpleCov.result.format! if Process.pid == pid
|
11
|
+
end
|
12
|
+
rescue LoadError
|
13
|
+
end
|
14
|
+
|
1
15
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
16
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
17
|
require 'rspec'
|
@@ -8,5 +22,5 @@ require 'multiprocessing'
|
|
8
22
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
23
|
|
10
24
|
RSpec.configure do |config|
|
11
|
-
|
25
|
+
|
12
26
|
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multiprocessing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- clicube
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-07-14 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description: Classes for inter-process synchronization/communication like thread library
|
15
14
|
in ruby standard library
|
@@ -20,8 +19,10 @@ extensions: []
|
|
20
19
|
extra_rdoc_files: []
|
21
20
|
files:
|
22
21
|
- .gitignore
|
22
|
+
- .yardopts
|
23
23
|
- Gemfile
|
24
24
|
- LICENSE.txt
|
25
|
+
- README.ja.md
|
25
26
|
- README.md
|
26
27
|
- Rakefile
|
27
28
|
- lib/multiprocessing.rb
|
@@ -29,44 +30,42 @@ files:
|
|
29
30
|
- lib/multiprocessing/externalobject.rb
|
30
31
|
- lib/multiprocessing/mutex.rb
|
31
32
|
- lib/multiprocessing/namedpipe.rb
|
32
|
-
- lib/multiprocessing/process.rb
|
33
33
|
- lib/multiprocessing/processerror.rb
|
34
34
|
- lib/multiprocessing/queue.rb
|
35
35
|
- lib/multiprocessing/semaphore.rb
|
36
36
|
- lib/multiprocessing/version.rb
|
37
37
|
- multiprocessing.gemspec
|
38
|
+
- spec/multiprocessing/conditionvariable_spec.rb
|
38
39
|
- spec/multiprocessing/mutex_spec.rb
|
39
|
-
- spec/multiprocessing/process_spec.rb
|
40
40
|
- spec/multiprocessing/queue_spec.rb
|
41
41
|
- spec/multiprocessing/semaphore_spec.rb
|
42
42
|
- spec/spec_helper.rb
|
43
43
|
homepage: https://github.com/clicube/multiprocessing
|
44
44
|
licenses: []
|
45
|
+
metadata: {}
|
45
46
|
post_install_message:
|
46
47
|
rdoc_options: []
|
47
48
|
require_paths:
|
48
49
|
- lib
|
49
50
|
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
-
none: false
|
57
56
|
requirements:
|
58
|
-
- -
|
57
|
+
- - '>='
|
59
58
|
- !ruby/object:Gem::Version
|
60
59
|
version: '0'
|
61
60
|
requirements: []
|
62
61
|
rubyforge_project:
|
63
|
-
rubygems_version:
|
62
|
+
rubygems_version: 2.0.0
|
64
63
|
signing_key:
|
65
|
-
specification_version:
|
64
|
+
specification_version: 4
|
66
65
|
summary: Inter-process synchronization/communication
|
67
66
|
test_files:
|
67
|
+
- spec/multiprocessing/conditionvariable_spec.rb
|
68
68
|
- spec/multiprocessing/mutex_spec.rb
|
69
|
-
- spec/multiprocessing/process_spec.rb
|
70
69
|
- spec/multiprocessing/queue_spec.rb
|
71
70
|
- spec/multiprocessing/semaphore_spec.rb
|
72
71
|
- spec/spec_helper.rb
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/processerror')
|
2
|
-
|
3
|
-
module MultiProcessing
|
4
|
-
class Process
|
5
|
-
|
6
|
-
attr_reader :pid
|
7
|
-
|
8
|
-
def initialize *args
|
9
|
-
raise ProcessError.new "mulst be called with a block" unless block_given?
|
10
|
-
@pid = fork do
|
11
|
-
yield *args
|
12
|
-
exit
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def value
|
17
|
-
th = ::Process.detach(@pid)
|
18
|
-
th.value
|
19
|
-
end
|
20
|
-
|
21
|
-
def join timeout=nil
|
22
|
-
th = ::Process.detach(@pid)
|
23
|
-
th.join timeout
|
24
|
-
end
|
25
|
-
|
26
|
-
def kill signal
|
27
|
-
::Process.kill signal, @pid
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
if $0 == __FILE__
|
34
|
-
include MultiProcessing
|
35
|
-
|
36
|
-
p = MultiProcessing::Process.new("nyan") do |str|
|
37
|
-
puts str
|
38
|
-
sleep 1
|
39
|
-
end
|
40
|
-
p p
|
41
|
-
p.join
|
42
|
-
end
|
43
|
-
|
@@ -1,51 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
describe MultiProcessing::Process do
|
4
|
-
|
5
|
-
it "can be created with block" do
|
6
|
-
MultiProcessing::Process.new{:nop}.should be_instance_of MultiProcessing::Process
|
7
|
-
end
|
8
|
-
|
9
|
-
it "cannot be created without block" do
|
10
|
-
proc{ MultiProcessing::Process.new }.should raise_error MultiProcessing::ProcessError
|
11
|
-
end
|
12
|
-
|
13
|
-
it "returns pid" do
|
14
|
-
MultiProcessing::Process.new{ :nop }.pid.should be_instance_of Fixnum
|
15
|
-
end
|
16
|
-
|
17
|
-
it "joins process" do
|
18
|
-
p = MultiProcessing::Process.new { :nop }
|
19
|
-
p.join.should_not be_nil
|
20
|
-
end
|
21
|
-
|
22
|
-
it "joins process with timeout" do
|
23
|
-
p = MultiProcessing::Process.new { :nop }
|
24
|
-
p.join(1).should_not be_nil
|
25
|
-
p = MultiProcessing::Process.new { sleep 1 }
|
26
|
-
p.join(0).should be_nil
|
27
|
-
end
|
28
|
-
|
29
|
-
it "returns value" do
|
30
|
-
p = MultiProcessing::Process.new { :nop }
|
31
|
-
p.value.should be_instance_of ::Process::Status
|
32
|
-
p = MultiProcessing::Process.new { :nop }
|
33
|
-
p.value.success?.should be_true
|
34
|
-
p = MultiProcessing::Process.new { exit 1 }
|
35
|
-
p.value.success?.should be_false
|
36
|
-
end
|
37
|
-
|
38
|
-
it "returns nil when process does not exist" do
|
39
|
-
p = MultiProcessing::Process.new { :nop }
|
40
|
-
p.join
|
41
|
-
p.value.should be_nil
|
42
|
-
end
|
43
|
-
|
44
|
-
it "can be kill" do
|
45
|
-
p = MultiProcessing::Process.new { sleep 1 }
|
46
|
-
p.kill :TERM
|
47
|
-
p.join(0).should be_nil
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|