I have an implementation of a network system based on Twisted. I noticed that when I run a function (which do some mathematical operations and prints the result) in a new thread, not in the main one, the print function causes Segmentation fault. Is it possible? Is there an option to avoid that?
My approach, based on Bram Cohen's suggestion:
Define a global Lock variable
from threading import Lock
s_print_lock = Lock()
Define a function to call print with the Lock
def s_print(*a, **b):
"""Thread safe print function"""
with s_print_lock:
print(*a, **b)
Use s_print instead of print in your threads.
You need to use a thread lock when you print something in a thread.
Example:
lock = Lock()
lock.acquire() # will block if lock is already held
print("something")
lock.release()
In this way the resource(in this case print) will not be used in the same time by multiple threads.
Using a thread lock is something like focusing the attention on the thread where the lock is acquired.
Related
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.
I have a thread (say thread_a) which execute a method (say method_a()). This method_a is calling method (say method_b) which uses a lock.I want to terminate this thread abruptly. How can I do this without damaging the consistency of the lock. Give bellow is a structure of my code,
def method_a()
#codes
method_b()
#codes
def method_b()
lock.acquire()
#codes
lock.release()
thread_a = threading.Thread(target=method_a)
thread_a.start()
What is the best way to terminate this thread_a. I want to keep the correct state of the lock even if the thread is killed abruptly. Any ideas?
I have a function that is used by multiple threads. Because of its nature, this function should only ever called once at a time. Multiple threads calling the function at the same time could be bad.
If the function is in use by a thread, other threads should have to wait for it to be free.
My background isn't coding so I'm not sure, but I believe this is called "locking" in the jargon? I tried Googling it up but did not find a simple example for Python3.
A simplified case:
def critical_function():
# How do I "lock" this function?
print('critical operation that should only be run once at a time')
def threaded_function():
while True:
# doing stuff and then
critical_function()
for i in range(0, 10):
threading.Thread(target=threaded_function).start()
from threading import Lock
critical_function_lock = Lock()
def critical_function():
with critical_function_lock:
# How do I "lock" this function?
print('critical operation that should only be run once at a time')
I am currently practicing python multi-thread module, and I write some code as below, but it is not working as I just expect.
import threading
import thread
import random
import time
lock = threading.RLock()
def func(lock):
print("In Thread " + threading.currentThread().getName())
lock.acquire()
time.sleep(random.random()*10)
lock.release()
print("Out Thread " + threading.currentThread().getName())
def start():
lock.acquire()
for i in range(5):
thread.start_new(func, (lock,))
lock.release()
# for i in range(5):
# thread.start_new(func, (lock,))
start()
print("test")
time.sleep(1)
lock.acquire()
print("main ends")
lock.release()
In my opinion, whether there is time.sleep(1) in the main thread does not count much for the new threads's running, because the lock is global and belongs to the main thread, the lock.acquire() operation would always work fine, so the main thread should not wait for those new threads to proceed. According to the property of thread.start_new(), when the main thread ends, all new threads would also stop. However, when I comment out the time.sleep() line, the program goes as what I have expected, but when I add this line in, the main thread always waits for new threads to finish.
This confuses me a lot and hope someone would explain to me the functionality of Rlock() as well as which thread does it belong to when I create it in the main thread while passing it to the sub-new thread and calling lock.acquire()?
A lock belongs to the thread that last did .acquire() it successfully, until it has been .release()d.
A RLock, short for re-entrant lock is a lock that can be acquired many times by the same thread that acquired it initially; the lock stays locked and held by the thread until each acquisition has been released.
The re-entrancy means here that the execution enters a section of code guarded by the lock, while the lock is held already. Your code does not demonstrate a case where a re-entrant lock is needed but suppose you have functions:
def guarded_op():
with lock:
print("Now doing 1 op")
another_op()
def another_op():
with lock:
print("Now did the another op")
A non-re-entrant lock would not work there, as the "lock was already locked" in guarded op; the locking would fail in another_op; but RLock works just fine.
By the way, you should always use the with statement with locks whenever possible to ensure their orderly release.
I have a thread code in python like this. But I am not sure whether I am doing in correct way or not.
Class MyThread(threading.thread):
def __init__(self, thread_id, thread_name):
self.thread_name = thread_name
self.thread_id = thread_id
def run(self):
do_something()
def do_something():
while True:
do_something_else()
time.sleep(5)
Class SomeClass:
def __init__():
pass
def run():
thread1 = MyThread(1, "thread1")
thread2 = MyThread(2, "thread2")
thread3 = MyThread(3, "thread3")
def main():
agent = Someclass()
agent.run()
Whether this is the safe way to deal with multiple thread? How does it impact other applications? Is there a chance, that execution of one thread can hinder the execution of others? What happens , if the threads got blocked in any cycle?
Also how to make sure that, thread doesn't gets blocked for forever b'coz of any reason. If it gets blocked , then after fixed timeinterval it should come out gracefully and continue in next loop.
That is why Python and some other languages introduce the lock
This page will help you, you need to read something about Lock, RLock and Condition
Your code's thread safety is really dependent on what's in do_something() and do_something_else(). It's thread safe if you're only modifying local variables. But the moment you start reading/modifying shared variables/storage, like a file or a global variable, then you need to use something like locks or semaphores to ensure thread safety.
You can read about Python's threading module here.
This Wikipedia articles on synchronization and locks may be helpful to you too.
If you need examples for writing multi-threading code, here's a good example using different synchronization mechanisms.