Re: Something is wrong with my threads
Robert Klemme <[email protected]>
| Newsgroups | gmane.comp.lang.ruby.general |
|---|---|
| Message-ID | <CAM9pMnNYv6MDwowbHSBdCDfb8wq+=zT-HQepcUJa-8cW1K2dXQ@mail.gmail.com> |
On Tue, Apr 23, 2019 at 9:39 AM Andy Jones <[email protected]> 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:[email protected]?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>