[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-talk
Subject:    Re: Something is wrong with my threads
From:       Robert Klemme <shortcutter () googlemail ! com>
Date:       2019-04-23 17:19:40
Message-ID: CAM9pMnNYv6MDwowbHSBdCDfb8wq+=zT-HQepcUJa-8cW1K2dXQ () mail ! gmail ! com
[Download RAW message or body]

On Tue, Apr 23, 2019 at 9:39 AM Andy Jones <Andy.Jones@jameshall.co.uk> wrote:
> 
> > But you are aware that this is not reliably possible no matter what you attempt, \
> > are you?
> 
> It's literally not possible in MRI because of the GIL.  Is that what you mean?

No. This has nothing to do with GIL. The reason is that the kernel is
free to schedule threads at its discretion. So even if 50 threads are
ready to run at the same time there are no guarantees as to when they
get CPU - at least on a non realtime OS.

> Yes, but jRuby doesn't have one, and two threads can genuinely call the same method \
> at the same time.  My test works fine in jRuby, but I need to ensure I've not \
> broken the code in MRI, too, so the test has to run there as well.

They *can* but you cannot force them to do so!

> Or do you mean that I can't guarantee for certain that two calls will happen at \
> exactly the same time?  Unfortunately true.  That's why I create 50 threads, each \
> calling the method, instead of two.  In the code you attach you do exactly the same \
> thing: call the method multiple times in threads hoping to get a collision.

Exactly.

> > A mutex guarantees that there are no two threads in the critical section. You do \
> > not need to prove that it works that way. > Others have done that for you \
> > already.
> 
> Well, there goes the entire of TDD...  How do I know I've used a mutex correctly?  \
> That I've synchronised the right bit of code? That I haven't introduced other \
> problems? This is why we test.  Or, why I test, anyway; YMMV.

Well, yes, but for a single method the test is pretty uninteresting.
If you want to do some multi threading stress testing you would have
to invoke several different methods / code paths that are all supposed
to use the same mutex. Even then you are not guaranteed to get the
Scott free card for multithreading - it will only tell you of issues
if they come up. Multi threading is one of the areas where I would say
testing can only be of limited help. Code / design reviews are
important here.

> For the record, I've re-read the docs on Thread and I think you are right: #run \
> doesn't guarantee that execution will switch to the thread.  (That's a hell of a \
> gotcha.) I've modified the test so that it counts the number of threads that _did_ \
> get woke, and uses that to work out what the expected results are.  It seems to \
> work fine now.  Thanks for your help.

Thread#run is not a method that should be used. Rather you use a
condition variable or other thread synchronization means. A barrier
could work well, too. (Not sure I have seen one in Ruby libraries
though but you could implement one using a ConditionVariable.)

Cheers

robert

-- 
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic