Pausing entire program from a thread spawned from a thread - python

My program currently looks something like this:
from threading import Thread
import time
def something():
time.sleep(10)
def function1():
if condition1:
Thread(target=something).start()
def function2():
if condition2:
Thread(target=something).start()
def function3():
if condition3:
Thread(target=something).start()
def main():
Thread(target=function1).start()
Thread(target=function2).start()
Thread(target=function3).start()
main()
If function 1 has already spawned a thread calling something() ,I dont want functions 2 and 3 to spawn another thread calling something().

Actually the code just creates three independent threads and each of these threads then can create another thread doing something, but again completely independent of each other (so getting 3 soemthing threads at max).
Now you ask that these threads interact in a certain manner: "something" should be executed just once. Hence thread "something" must be instantiated only one time and the call must be secured with a lock. Function threads must know about that "something" thread, so you need to create "something" thread in main() and pass it to the function threads.
All in all I am not sure that this will give a simple program structure and it might be good to revise what you want to achieve.

Try following pseudo-code:
import threading
import time
lock = threading.Lock()
def something():
time.sleep(10)
def function1():
if condition1 and lock.acquire(timeout=5):
threading.Thread(target=something).start()
def function2():
if condition2 and lock.acquire(timeout=5):
threading.Thread(target=something).start()
def function3():
if condition3 and lock.acquire(timeout=5):
threading.Thread(target=something).start()
def main():
threading.Thread(target=function1).start()
threading.Thread(target=function2).start()
threading.Thread(target=function3).start()
main()

Related

awaiting future never reached, although set_result() is called

My example class uses only two methods,
async def run(): creates a asyncio.Future() and awaits it
def stop(): sets the result of the Future() created by the run() method
The idea is to use the python signal handler to call the stop() function once a signal is received. The stop() then sets the result of the Future() the run() is waiting for. So far so good, but this does not work. Actually, the run() method never notices that the Future() is done.
Example code:
import asyncio
import signal
class Foo:
def __init__(self):
self._stop = None
async def run(self):
print(f"1. starting foo")
self._stop = asyncio.Future()
await self._stop
print(f"4. 'stop' called, canceling running tasks...")
def stop(self):
print(f"3. stopping foo")
self._stop.set_result(None)
f = Foo()
loop = asyncio.new_event_loop()
def signal_handler(_, __):
print(f"2. signal handler: call Foo.stop()")
f.stop()
signal.signal(signal.SIGINT, signal_handler)
loop.run_until_complete(f.run())
print(f"5. bye")
and the output is:
1. starting foo
2. signal handler: call Foo.stop()
3. stopping foo
That's it. The fourth print entry is never called. Although the self._stop Future is done after setting the result.
Does anyone have any idea what I am doing wrong and what I am missing?
Any help would be greatly appreciated!
I cannot reproduce your problem, but it is quite possible that it'll happen on different operating systems.
Per loop.add_signal_handler:
Unlike signal handlers registered using signal.signal(), a callback registered with this function is allowed to interact with the event loop.
The usual culprit that causes those issues is the event loop not waking up from outside input.
There are 2 solutions for your issue:
If you're using unix, change signal.signal() to loop.add_signal_handler().
If not, try changing f.stop() to loop.call_soon_threadsafe(f.stop). It will make sure that the event loop wakes up correctly.
Irrespective to that, you have a couple of different issues arising from using asyncio.new_event_loop() and not assigning the loop to the thread or cleaning up correctly. I suggest you to use asyncio.run().

Python3: How to stop/kill thread

My code runs N number of threads. I want to stop specific threads on some condition but the remaining threads should continue running. I am doing some operation once each thread finishes its job. Is there a way to stop running thread in Python 3.
My current code is implemented in Python2 which does this by "_Thread__stop()". Is there any identical thing in Python3?
The practice is to "signal" the thread that it is time to finish and then the thread needs to exit. This is not killing like you kill a process but a regular state machine behavior of your thread function.
For example, suppose your thread is lopping. You should insert an if statement inside the loop that instructing the thread function to break or return if stop is True. The stop variable should be a shared variable with the main thread (or the thread who need to stop out thread) that will change it to True. usually after this, the stopper thread will want to wait for the thread completion by join()
It's a bad habit to kill a thread, better is to create a "flag" which will tell you when your thread made its work done.
Consider the following example:
import threading
import random
class CheckSomething(threading.Thread):
def __init__(self, variable):
super(CheckSomething, self).__init__()
self.start_flag = threading.Event()
self.variable = variable
def check_position(self, variable):
x = random.randint(100)
if variable == x:
self.stop_checking()
def run(self):
while True:
self.check_position(self.variable)
def stop_checking():
self.start_flag.set()
def stopped():
return self.start_flag.is_set()
The set() method of Event() set its status to True. More you can read in docs: https://docs.python.org/3.5/library/threading.html
So you need to call stop_checking() when you meet a condition where you want exit.

Continuous loop using threading

I am somewhat new to python. I have been trying to find the answer to this coding question for some time. I have a function set up to run on a threading timer. This allows it to execute every second while my other code is running. I would like this function to simply execute continuously, that is every time it is done executing it starts over, rather than on a timer. The reason for this is that due to a changing delay in a stepper motor the function takes different amounts of time run.
Is this what you're looking for?
from threading import Thread
def f():
print('hello')
while True:
t = Thread(target=f)
t.start()
t.join()
Or maybe this, which shows the concurrent paths of execution (for production, remove sleep() calls, of course):
from threading import Thread
from time import sleep
def g():
print('hello')
sleep(1)
def f():
while True: g()
Thread(target=f).start()
sleep(1)
print('other code here')

Executing a function in new process with Python

Is there a way to do this? I was thinking maybe use subprocess or multiprocessing but I am not sure how to do this?
I don't have any code for an example because it is just a general question.
http://docs.python.org/library/subprocess.html
EDIT: Probably, I missed, what you want. Well, It all I can imagine about your question.
subprocess.call(["ls","-lAd"]) # executes external program. Like system()
# Capture output. Like popen, as I remember.
subprocess.check_output(["echo", "Hello World!"])
os.fork() # Binding to fork()
class MyThread(threading.thread):
def run():
print("Hello from thread")
MyThread().start()
yes there is
python provides 2 different ways of doing this threading and multiprocessing witch one you should use depend on the operation your performing.
the main difference is that Threading executes the function in the same interpreter while multiprocessing starts a new interpreter and runs the function in that interpreter. this means that multiprocessing is genraly used when your performing cpu bound operations like adding a lot of numbers and Thread is used for iobound operations like inputs or waiting for something to happen.
threading Example:
from threading import Thread
import time
def fun(a):
global myVar
myVar = "post start" # as you can see myVar is updated and can be read by the main Thread
time.sleep(1)
f = input(a)
print(f"inputed {f}")
myVar = "preThread"
t = Thread(target=fun,
args=("plz input your message ",))
t.start() # start the thread
print("this whil run after the thread started", myVar)
t.join() # wait for thread to finisch executing
print("this whil run after the thread ended", myVar)
outputs
this whil run after the thread started post start
plz input your message k
inputed k
this whil run after the thread ended post start
if you use the multiprocessing lib it starts a new python interpreter and all values are copied into it, and print and inputs wont work
from multiprocessing import Process
import time
def fun(a):
global myVar
myVar = "post start" # as you can see myVar is updated and can be read by the main Thread
time.sleep(1)
f = input(a)
print(f"inputed {f}")
myVar = "preThread"
t = Process(target=fun,
args=("plz input your message ",))
t.start() # start the thread
print("this whill run after the thread started", myVar)
t.join() # wait for thread to finisch executing
print("this whill run after the thread ended", myVar)
outputs:
this whill run after the thread started preThread
this whill run after the thread ended preThread
if you want to know more plz read
https://docs.python.org/3/library/threading.html for thread
https://docs.python.org/3/library/multiprocessing.html for multiprocessing\

Python thread doesn't work as expected

well,I wrote a little snappet trying to know how to use python threading .
But strangely the following code just quit quickly without the expected output.
Is it because I shouldn't spawn threads by overiding the run() method?
import threading
from time import sleep
class mythread(threading.Thread):
def __init__(self,target=None,thread_num=5):
threading.Thread.__init__(self,target=None)
self.thn = thread_num
def run(self):
for i in range(self.thn):
t = threading.Thread(target=self.myfunc)
t.start()
t.join()
myfunc(self.thn)
def myfunc(num):
print num,'\tI am doing sth.'
sleep(0.5)
print num,'\tI have done it.'
mythread()
You need to start the thread to make it actually do something:
t = mythread()
t.start()
If you bother to accept a target parameter in your constructor (why?), you shouldn't ignore this parameter. Maybe you want to pass it on to the Thread constructor. (Why?)
When you write mythread(), you instantiate the object. THe default constructor will be called, so __init__() will be executed.
You constructor doesn't have the any instruction of starting the thread.

Categories

Resources