Thread library in the following code isn't work - python

what's the problem in the code below?
It only shows two arrows when I run it
Of course, the first was the import thread, but because it gave an error (no module named 'thread'), I changed it to import threading
import threading
import turtle
def f(painter):
for i in range(3):
painter.fd(50)
painter.lt(60)
def g(painter):
for i in range(3):
painter.rt(60)
painter.fd(50)
try:
pat=turtle.Turtle()
mat=turtle.Turtle()
mat.seth(180)
thread.start_new_thread(f,(pat,))
thread.start_new_thread(g,(mat,))
turtle.done()
except:
print("hello")
while True:
pass

threaing and thread are separate modules to deal with threads in python. However thread module is considered as deprecated in python3 but renamed to _thread for backward compatibility. In your case i assume you are trying to use _thread module with python3.
So your code should be as follows.
import _thread
import turtle
def f(painter):
for i in range(3):
painter.fd(50)
painter.lt(60)
def g(painter):
for i in range(3):
painter.rt(60)
painter.fd(50)
try:
pat=turtle.Turtle()
mat=turtle.Turtle()
mat.seth(180)
_thread.start_new_thread(f,(pat,))
_thread.start_new_thread(g,(mat,))
turtle.done()
except:
print("Hello")
while True:
pass
since _thread module is deprecated, it is better you move to threading module.

Related

Passing Variables to a process python

Need help with how to modify/fix code to allow me to control what is occurring in a process. I have looked around and read I need to either make a global variable which the process can read or use an event function to trigger the process. Problem though is I don't know how to implement them in a class function. I thought that if I followed pyimagesearch code that it would work but it appears that it only works with the threading module and not the multiprocessing module.
import RPi.GPIO as GPIO
from RPI.GPIO import LOW,OUT,HIGH,BCM
import multiprocessing as mp
import time
class TestClass():
def __init__(self,PinOne=22,PinTwo=27):
self.PinOne = PinOne
self.PinTwo = PinTwo
self.RunningSys = True
GPIO.setmode(BCM)
GPIO.setup(PinOne,OUT)
GPIO.output(PinOne,LOW)
GPIO.setup(PinTwo,OUT)
GPIO.output(PinTwo,LOW)
def Testloop(self):
while self.RunningSys:
GPIO.output(PinOne,HIGH)
GPIO.output(PinTwo,HIGH)
time.sleep(1)
GPIO.output(PinOne,LOW)
GPIO.output(PinTwo,LOW)
GPIO.output(PinOne,LOW)
GPIO.output(PinTwo,LOW)
def StopPr(self):
self.RunningSys = False
def MProc(self):
MPGP = mp.process(target=TestClass().Testloop())
MPGP.start()
MPGP.join()
In a separate script
From testfile import TestClass
import time
TestClass().MProc()
time.sleep(4)
TestClass().StopPr()

Timeout Function in Python (For Windows)

Is there a clear way to create a timeout function like the signal module but is compatible with Windows? Thanks
Yes, it can be done in windows without signal and it will also work in other os as well. The logic is to create a new thread and wait for a given time and raise an exception using _thread(in python3 and thread in python2). This exception will be thrown in the main thread and the with block will get exit if any exception occurs.
import threading
import _thread # import thread in python2
class timeout():
def __init__(self, time):
self.time= time
self.exit=False
def __enter__(self):
threading.Thread(target=self.callme).start()
def callme(self):
time.sleep(self.time)
if self.exit==False:
_thread.interrupt_main() # use thread instead of _thread in python2
def __exit__(self, a, b, c):
self.exit=True
Usuage Example :-
with timeout(2):
print("abc")
#other stuff here
The program in the with block should exit within 2 seconds otherise it will be exited after 2 seconds.

Multiple thread with Autobahn, ApplicationRunner and ApplicationSession

python-running-autobahnpython-asyncio-websocket-server-in-a-separate-subproce
can-an-asyncio-event-loop-run-in-the-background-without-suspending-the-python-in
Was trying to solve my issue with this two links above but i have not.
I have the following error : RuntimeError: There is no current event loop in thread 'Thread-1'.
Here the code sample (python 3):
from autobahn.asyncio.wamp import ApplicationSession
from autobahn.asyncio.wamp import ApplicationRunner
from asyncio import coroutine
import time
import threading
class PoloniexWebsocket(ApplicationSession):
def onConnect(self):
self.join(self.config.realm)
#coroutine
def onJoin(self, details):
def on_ticker(*args):
print(args)
try:
yield from self.subscribe(on_ticker, 'ticker')
except Exception as e:
print("Could not subscribe to topic:", e)
def poloniex_worker():
runner = ApplicationRunner("wss://api.poloniex.com:443", "realm1")
runner.run(PoloniexWebsocket)
def other_worker():
while True:
print('Thank you')
time.sleep(2)
if __name__ == "__main__":
polo_worker = threading.Thread(None, poloniex_worker, None, (), {})
thank_worker = threading.Thread(None, other_worker, None, (), {})
polo_worker.start()
thank_worker.start()
polo_worker.join()
thank_worker.join()
So, my final goal is to have 2 threads launched at the start. Only one need to use ApplicationSession and ApplicationRunner. Thank you.
A separate thread must have it's own event loop. So if poloniex_worker needs to listen to a websocket, it needs its own event loop:
def poloniex_worker():
asyncio.set_event_loop(asyncio.new_event_loop())
runner = ApplicationRunner("wss://api.poloniex.com:443", "realm1")
runner.run(PoloniexWebsocket)
But if you're on a Unix machine, you will face another error if you try to do this. Autobahn asyncio uses Unix signals, but those Unix signals only work in the main thread. You can simply turn off Unix signals if you don't plan on using them. To do that, you have to go to the file where ApplicationRunner is defined. That is wamp.py in python3.5 > site-packages > autobahn > asyncio on my machine. You can comment out the signal handling section of the code like so:
# try:
# loop.add_signal_handler(signal.SIGTERM, loop.stop)
# except NotImplementedError:
# # signals are not available on Windows
# pass
All this is a lot of work. If you don't absolutely need to run your ApplicationSession in a separate thread from the main thread, it's better to just run the ApplicationSession in the main thread.

thread fails to start if wx.app.mainloop isn't called from the main module

I'm hoping someone can explain this behavior to me. If I import a module that starts a wxpython interface, threads are unable to start until after the app.MainLoop() ends. Simplest example:
simple_app.py
import wx
from threading import Thread
def test():
from time import sleep
while 1:
print("thread still running")
sleep(2)
app = wx.App()
frame = wx.Frame(None, -1, 'simple.py')
frame.Show()
thread = Thread(target=test)
thread.setDaemon(True)
thread.start()
app.MainLoop()
main.py
import simple_app
If you run simple_app.py by itself it works fine, if you run main.py the thread never starts... Why? I have a feeling it has to do with the thread being unable to secure a lock.
The second thread in simple_app.py is trying to import the time module while an import is already running, which leads to deadlock when simple_app is being imported from the main module. Because imports acquire interpreter's import lock for the current thread while importing a module. It has been documented.
Threads in the main module can import other modules that's why running simple_app.py as main module works. Moving from time import sleep to module level in simple_app.py solves the problem.
Running the following code helps better understand the problem;
my_time.py
from time import sleep
simple_app.py
import imp
import sys
from threading import Thread
from time import sleep
import wx
class MyFinder(object):
def __init__(self):
print('MyFinder initializing')
if imp.lock_held():
while imp.lock_held():
print('import lock held')
sleep(2)
print('import lock released')
else:
print('import lock is not held')
def find_module(self, module, package=None):
print('MyFinder.find_module called with module name "{}", pakcage name "{}"'.format(module, package))
return None
def test():
sys.meta_path.append(MyFinder())
from my_time import sleep
count = 0
while True:
print("{} thread still running".format(count))
count += 1
sleep(2)
app = wx.App()
frame = wx.Frame(None, -1, 'simple.py')
frame.Show()
thread = Thread(target=test)
thread.setDaemon(True)
thread.start()
app.MainLoop()
This was a quite interesting problem. The issue at hand was not quite obvious (at least to me).
The last line of simple_app.py blocks until frame is closed/destroyed. Therefore if started from main.py the import will finish only (and show output from print), when the frame is closed.
Try the following instead (normally you would structure your program better to start/stop the app where you need it):
In simple_app.py change last line to:
if __name__ == '__main__':
app.MainLoop()
In main.py
import wx
import simple_app
app = wx.GetApp()
app.MainLoop()
I can not tell you why exactly there is a difference on running directly and on importing (running directly shows the result of print, but importing does not).

Strange problems when using requests and multiprocessing

Please check this python code:
#!/usr/bin/env python
import requests
import multiprocessing
from time import sleep, time
from requests import async
def do_req():
r = requests.get("http://w3c.org/")
def do_sth():
while True:
sleep(10)
if __name__ == '__main__':
do_req()
multiprocessing.Process( target=do_sth, args=() ).start()
When I press Ctrl-C (wait 2sec after run - let Process run), it doesn't stop. When I change the import order to:
from requests import async
from time import sleep, time
it stops after Ctrl-C. Why it doesn't stop/kill in first example?
It's a bug or a feature?
Notes:
Yes I know, that I didn't use async in this code, this is just stripped down code. In real code I use it. I did it to simplify my question.
After pressing Ctrl-C there is a new (child) process running. Why?
multiprocessing.__version__ == 0.70a1, requests.__version__ == 0.11.2, gevent.__version__ == 0.13.7
Requests async module uses gevent. If you look at the source code of gevent you will see that it monkey patches many of Python's standard library functions, including sleep:
request.async module during import executes:
from gevent import monkey as curious_george
# Monkey-patch.
curious_george.patch_all(thread=False, select=False)
Looking at the monkey.py module of gevent you can see:
https://bitbucket.org/denis/gevent/src/f838056c793d/gevent/monkey.py#cl-128
def patch_time():
"""Replace :func:`time.sleep` with :func:`gevent.sleep`."""
from gevent.hub import sleep
import time
patch_item(time, 'sleep', sleep)
Take a look at the code from the gevent's repository for details.

Categories