1

Is it possible to run two threads simultaneously? For example...

I have two classes like this...

import threading

class Thread1(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        print("Thread1")

class justAClass(object):
    def do_soemthing(self):
        print("Thread2")

if __name__ == "__main__":
    total = 0
    thread_limit = 200
    while True:
        if threading.activeCount() < thread_limit:
            Thread1().start()
    # I will never run because I want to wait until while True has finished to run!
    t = threading.Timer(1.0, justAClass().do_soemthing())
    t.start()

If you run this code you will see that Tread2 never gets printed out because the Thread2 has to wait for Thread1 to finished (which it never will because of the While statement.

What I'm after is for both Thread1 and Thread2 to run at the same time independent of each other.

zmo
  • 24,463
  • 4
  • 54
  • 90
Prometheus
  • 32,405
  • 54
  • 166
  • 302
  • How exactly are you testing this and reaching the relevant conclusion? As-written, this code should be properly threaded, unless library code you're invoking has mutexes. – Charles Duffy May 11 '14 at 19:21
  • 2
    @OutlawLemur, I don't think these are duplicate questions; this one has a specific implementation which is claimed to be failing (though not specific/complete enough to be runnable, making it hard to test answers to be correct and impossible to test hunches; the OP should probably see http://sscce.org/) – Charles Duffy May 11 '14 at 19:22
  • @Charles Duffy the code is threaded, thats not the issue. The issue is I would like to run two completely different threads 'simultaneously'. At the moment the first thread 'function' threading.Timer runs and you would have to wait until that is done (which it will never finished) until the seconds thread case runs. I want both the timer and the stree_test function to run at the same time independence of eachother – Prometheus May 11 '14 at 19:26
  • 2
    @Spike, "simultaneously" meaning what? You can't have both threads be in the Python interpreter itself simultaneously on account of the GIL. You *can* have them both running at other times -- ie. thread A is doing IO, thread B has the GIL and is doing CPU. – Charles Duffy May 11 '14 at 19:29
  • @Spike each time you call `Thread.start()`, a new thread is running, so basically the timer is definitely running in parallel of your `while True` loop, and depending on the implementation of the threads returned by your `stress_test()` function, each one is being launched in parallel. Hard to tell without code. – zmo May 11 '14 at 19:29
  • 1
    ...anyhow, if we had a reproducer complete enough to reproduce whatever leads you to think they're not running simultaneously, we could actually help. You haven't provided such a thing, so we can't. – Charles Duffy May 11 '14 at 19:30
  • @zmo in my tests that is not the case, Thread 1 (call it timer) will not run until Thread 2 (call it stress_test) has completed – Prometheus May 11 '14 at 19:31
  • @Charles Duffy I'll post the full code I created in the OP, give me a sec. – Prometheus May 11 '14 at 19:32
  • @Spike, that may be that the TOR code is enforcing mutexes, so you have one thread waiting around for a mutex before it can do anything. That should be easy to discover -- instead of doing tor calls, just do sleeps and print statements, and see if you still have a problem. – Charles Duffy May 11 '14 at 19:32
  • 1
    well, that's not what we can read from your code. If you want us, please make a [Simple Short Concise Correct Example](http://sscce.org). Please help us help you. – zmo May 11 '14 at 19:32
  • 1
    @Spike, we don't want the *full* code, but a smaller subset of your code we can execute. cf last comment, SSCCE. – zmo May 11 '14 at 19:33
  • @zmo Sorry, I'll try not to add the full code to the OP, I have now added have I think will help you to see what I'm trying to do. – Prometheus May 11 '14 at 19:35
  • ...so, here's the thing -- this is very, *very* much not self-contained; we have to have a tor proxy to run it. As such, it's unnecessarily hard for anyone to test a proposed solution or reproduce your problem. A SSCCE isn't just to make it easy for folks to read your problem, but also to make it easy to check that a solution is correct. – Charles Duffy May 11 '14 at 19:36
  • @Charles Duffy ok give me a few mins, I write a test that hopefully you can run. – Prometheus May 11 '14 at 19:39
  • @Charles, Please accept my apologies, I hope the above helps explain better now my issue. hopefully it now makes more sense and can be run so you see what I mean – Prometheus May 11 '14 at 19:52
  • 2
    You've written an infinite loop, so you will never leave the `while True` loop. You must have some condition to terminate the loop in order to proceed. – b4hand May 11 '14 at 20:14
  • +1 to the question, now that it's clearly written. :) – Charles Duffy May 11 '14 at 20:37

1 Answers1

3
while True:
    if threading.activeCount() < thread_limit:
        Thread1().start()
# I will never run because I want to wait until while True has finished to run!
t = threading.Timer(1.0, justAClass().do_soemthing())
t.start()

obviously that's the case! And as you're never getting out of the loop, the code below the comment is unreachable.

Though, your first code was:

tor.connect()
tor.new_identity()

t = threading.Timer(10.0, tor.new_identity())
t.start()

total = 0
thread_limit = 200
while True:
    if threading.activeCount() < thread_limit:
        stress_test(host_ip, host_port).start()

And there you were initiating the Timer before the infinite loop, so your Timer thread was definitely working, as we said in our comments. To make your SSCCE work correctly, here comes the fix:

import threading
import time

class Thread1(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        time.sleep(1)
        print("Thread1")

class justAClass(object):
    def do_something(self, pause):
        while True:
            time.sleep(pause)
            print("Thread2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")

if __name__ == "__main__":
    total = 0
    thread_limit = 200
    t = threading.Timer(1.0, justAClass().do_something, args=(1.0,))
    t.start()
    while True:
        if threading.activeCount() < thread_limit:
            Thread1().start()

Though, be aware that your timer thread, with the do_something function as it is, will only run once, unless you rearm it from within the thread, or you build a while loop within.

BTW, I fixed another mistake in your code I did not see at first, you're calling the timer over the do_something function, be if you pass the do_something function with parens at the end do_something(), it will be evaluated in your main thread as you're creating the timer, and then you'll be passing the result of the function to the Timer function... Whereas if you do not use the parens, you're giving the function object itself to Timer() which will then be able to call it after the delay.

is there a way to get the timer to run every x seconds while still allowing the other function to run?

of course:

class justAClass(object):
    def do_something(self, pause):
        while True:
            time.sleep(pause)
            print("Thread2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
zmo
  • 24,463
  • 4
  • 54
  • 90