ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Below is a program that I wrote that uses the Lucas Lehmer algorithm to figure out if a number is a mersenne prime (2^prime number-1). In my program it is trying to determine if 2^NUM_TO_CHECK-1 is a prime. Using the code below it only runs the "t_run" thread and not the "t_progress" thread until t_run has finished. Is my code not thread safe or something? Any incite would be greatly appreciated.
I found out if I put a delay/time.sleep in this loop, the threads work fine together. The problem is, I will be doing millions of calculations and can't sleep here or my calculations will never complete. Any way to make this work as intended?
Code:
while (self.i <= NUM_TO_CHECK-2):
self.answer = gmpy2.f_mod(((self.testnum*self.testnum)-2), self.num)
self.testnum = self.answer
self.i += 1
time.sleep(1) #IF I DO THIS, BOTH THREADS WORK FINE.
I read all about locking, I think that is my issue. Below is using RLock in both of my threads. For small numbers that I am checking it appears that using the RLock works as desired. When I calculate big numbers, t_progress only runs once every 10 seconds at most, even though I only sleep 1 second between each loop. I have tried threading.Lock(), threading.RLock(), threading.Semaphore(), and so far RLock() seems the closest, it just still isn't giving the desired result though.
You should minimize the amount time spent holding the lock. In this case, the only shared resource are the variables self.progress and self.i, so only hold the lock while reading and writing them.
Currently your lucaslehmer thread is hold the lock almost all of the time, including while it's doing the main f_mod calculation, which is why your other thread has a hard time obtaining the lock.
You should minimize the amount time spent holding the lock. In this case, the only shared resource are the variables self.progress and self.i, so only hold the lock while reading and writing them.
Currently your lucaslehmer thread is hold the lock almost all of the time, including while it's doing the main f_mod calculation, which is why your other thread has a hard time obtaining the lock.
It is running a lot better locking when only using the shared resources. It is still a little glitchy as far as not necessarily running t_progress every second, but it is close enough that I am not worried about it. Thanks for your help!
In any language, every piece of code that is accessing a shared resource must "obtain a 'covering lock'" that will serialize access to that resource, before manipulating that resource. Then, it must release that lock as soon as possible thereafter.
Since the process of acquiring and releasing locks is expensive, even if no blocking occurs, you should be prudent in arranging your scheme so that the number of lock/unlock cycles is, within reason, minimized.
"Progress displays" are also very expensive. It is usually a good idea to maintain simple counters in the "worker" threads which can be periodically examined by a separate, timed thread which generates the progress displays. (And, generally, that thread can just retrieve the current counter-values without bothering with a lock on those values: any value obtained will be "close enough.")
Finally: threading will not speed up a CPU-bound activity, except to the extent that it might leverage "multiple cores" and then only if the implementation actually does so.
Last edited by sundialsvcs; 01-02-2017 at 09:06 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.