So I have been looking at some code I inherited. I see two examples of thread use in this. Wondering what the difference is. I've made up two examples that show this, wondering what the difference is, and why to use one or the other. ---Example 1----------------------------------------------------------- obj1 = SomeObject.new() obj2 = SomeOtherObject.new() obj3 = "helloworld" Thread.start(obj1, obj2, myString) do |thing1, thing2, thing3| #use the variables named thing1, thing2, thing3. end ----------------------------------------------------------------------- And then this way... ---Example 2----------------------------------------------------------- obj1 = SomeObject.new() obj2 = SomeOtherObject.new() obj3 = "helloworld" Thread.start() do #use the objects named obj1, obj2, obj3 end ----------------------------------------------------------------------- So, What is the reason for doing Example 1 versus Example 2. The 2nd example seems simpler in my book. My guess is it has something to do with how the objects may be used outside the thread?
on 2012-12-30 02:37
on 2012-12-30 03:54
x = 10
t = Thread.start do
x = 20
puts "In thread, x's value is: %s" % x
end
t.join
puts "In main thread, x's value is: #{x}"
--output:--
In thread, x's value is: 20
In main thread, x's value is: 20
================
x = 10
t = Thread.start(x) do |y|
y = 20
puts "In thread, y's value is: %s" % y
end
t.join
puts "In main thread, x's value is: #{x}"
--output:--
In thread, y's value is: 20
In main thread, x's value is: 10
===========
However,
x = 'hello'
t = Thread.start(x) do |y|
y << ' world'
puts "In thread, y's value is: %s" % y
end
t.join
puts "In main thread, x's value is: #{x}"
--output:--
In thread, y's value is: hello world
In main thread, x's value is: hello world
on 2012-12-30 12:22
On Sun, Dec 30, 2012 at 2:38 AM, Grant Schoep <lists@ruby-forum.com> wrote: > So, What is the reason for doing Example 1 versus Example 2. The 2nd > example seems simpler in my book. My guess is it has something to do > with how the objects may be used outside the thread? See 7stud's examples. It's not about objects but about scope of variables. Here's another way to demonstrate the effect: $ ruby -e 'for i in 0..4; Thread.new(i) {|n| sleep 1;p [i,n]} end;sleep 2' [4, 3] [4, 4] [4, 2] [4, 1] [4, 0] Kind regards robert
on 2012-12-30 13:44
On 30 December 2012 21:21, Robert Klemme <shortcutter@googlemail.com> wrote: > $ ruby -e 'for i in 0..4; Thread.new(i) {|n| sleep 1;p [i,n]} end;sleep 2' > [4, 3] > [4, 4] > [4, 2] > [4, 1] > [4, 0] > > Kind regards > > robert > So does that mean these are functionally identical? Thread.new(a) { |b| do_something_with b } .. and .. Thread.new { b=a; do_something_with b } Or is there a potential race condition caused by possibly deferred execution of the block, which is avoided by performing the "renaming" assignment in the parent thread? I'm trying to think of an example, but am having trouble. -- Matthew Kerwin, B.Sc (CompSci) (Hons) http://matthew.kerwin.net.au/ ABN: 59-013-727-651 "You'll never find a programming language that frees you from the burden of clarifying your ideas." - xkcd
on 2012-12-30 14:10
On 30 December 2012 22:43, Matthew Kerwin <matthew@kerwin.net.au> wrote: >> >> > > Or is there a potential race condition caused by possibly deferred > execution of the block, which is avoided by performing the "renaming" > assignment in the parent thread? I'm trying to think of an example, but am > having trouble. > Thought of one (sorry for replying to myself): a = 1 loop do Thread.new { b=a; p b } a += 1 end .. where `a += 1` is likely to run before `b=a`; as opposed to .. a = 1 loop do Thread.new(a) { |b| p b } a += 1 end .. where passing the value of _a_ to Thread#new is guaranteed to happen before `a += 1`, so _b_ will always have the right value. -- Matthew Kerwin, B.Sc (CompSci) (Hons) http://matthew.kerwin.net.au/ ABN: 59-013-727-651 "You'll never find a programming language that frees you from the burden of clarifying your ideas." - xkcd
on 2012-12-30 14:15
On Sun, 30 Dec 2012 13:43:53 +0100, Matthew Kerwin <matthew@kerwin.net.au> wrote: > assignment in the parent thread? I'm trying to think of an example, but am > having trouble. There's another thing apart from the race conditions. These are mostly equivalent (except for what you've already said) only if there is no variable called `b` in the outer scope - if there was one, in your second example `b=a` will assign to it and change the value outside the thread. In the first case, the "outer" `b` will simple be inaccessible inside the thread, but its value outside the thread won't be changed. (The above only applies to Ruby 1.9 and newer, the semantics for both versions on 1.8 are the same - if there is an "outer" b, its value will change. This is obviously not always what the coder has intended and so it was changed in 1.9.)
on 2012-12-30 21:12
On Sun, Dec 30, 2012 at 2:09 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote: > On 30 December 2012 22:43, Matthew Kerwin <matthew@kerwin.net.au> wrote: >> >> On 30 December 2012 21:21, Robert Klemme <shortcutter@googlemail.com> >> wrote: >>> >>> On Sun, Dec 30, 2012 at 2:38 AM, Grant Schoep <lists@ruby-forum.com> >>> wrote: >>> Here's another way to demonstrate the effect: >>> >>> $ ruby -e 'for i in 0..4; Thread.new(i) {|n| sleep 1;p [i,n]} end;sleep >>> 2' >>> [4, 3] >>> [4, 4] >>> [4, 2] >>> [4, 1] >>> [4, 0] > a += 1 > .. where passing the value of _a_ to Thread#new is guaranteed to happen > before `a += 1`, so _b_ will always have the right value. This race condition is what my example posted earlier demonstrates. You can change it a bit to make it more similar to your a+=1 example: $ ruby -e 'a=0; 4.times {Thread.new(a) {|n| sleep 1;p [a,n]}; a+=1}; sleep 2' [4, 1] [4, 0] [4, 2] [4, 3] Kind regards robert
on 2012-12-30 22:01
Matthew Kerwin wrote in post #1090641: > > Thought of one (sorry for replying to myself): > > a = 1 > loop do > Thread.new { b=a; p b } > a += 1 > end > > .. where `a += 1` is likely to run before `b=a`; What makes you think that?
on 2012-12-31 00:27
7stud -- <lists@ruby-forum.com> wrote: > > .. where `a += 1` is likely to run before `b=a`; > > What makes you think that? Experience in multithreaded environments. Without an explicit mutex or other locking mechanism (or call to Thread#join) there's no guarantee that either will run before the other. I know that in MRI the GVL is a large player, but I'm not being implementation-specific here. If I really had to guess, in a truly parallel multithreaded environment, assuming that the block begins execution at the same instant as the line after Thread.new, I'd guess that the `b=a` operation would happen before the `a = ...`, assuming that `a += 1` is actually broken down into `a = a + 1` which has an extra operation and so should take longer. However in a less parallel system I would have assumed the current thread would execute a bit before the child thread was given some CPU time, so `a += 1` would have a chance to complete before `b=a`. In either case it's something over which I as the programmer do not have any control. Matma Rex <matma.rex@gmail.com> wrote: > There's another thing apart from the race conditions. These are mostly equivalent (except for what you've already said) only if there is no variable called `b` in the outer scope - if there was one, in your second example `b=a` will assign to it and change the value outside the thread. In the first case, the "outer" `b` will simple be inaccessible inside the thread, but its value outside the thread won't be changed. Ah, that's a really good point. I'd forgotten that 1.9 masks variables with the same name as block parameters. Now that you've said it, I remember having to refactor a bunch of OptParse code that used to use: on('-x', Integer, 'foobar') {|$x| } -- Matthew Kerwin, B.Sc (CompSci) (Hons) http://matthew.kerwin.net.au/ ABN: 59-013-727-651 "You'll never find a programming language that frees you from the burden of clarifying your ideas." - xkcd
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.