How do I do threading in python? - python

I am trying to learn how to use threads with python. this is the code I have been studying:
import time
from threading import Thread
def myfunc(i):
print "sleeping 5 sec from thread %d" % i
time.sleep(5)
print "finished sleeping from thread %d" % i
for i in range(10):
t = Thread(target=myfunc, args=(i,))
t.start()
the program runs fine in command prompt but when I try to run it in idle I get errors like this:
Traceback (most recent call last):
File "C:\Python24\lib\lib-tk\Tkinter.py", line 1345, in __call__
return self.func(*args)
File "C:\Python24\lib\idlelib\ScriptBinding.py", line 165, in run_module_event
interp.runcode(code)
File "C:\Python24\lib\idlelib\PyShell.py", line 726, in runcode
self.tkconsole.endexecuting()
File "C:\Python24\lib\idlelib\PyShell.py", line 901, in endexecuting
self.showprompt()
File "C:\Python24\lib\idlelib\PyShell.py", line 1163, in showprompt
self.resetoutput()
File "C:\Python24\lib\idlelib\PyShell.py", line 1178, in resetoutput
self.text.insert("end-1c", "\n")
File "C:\Python24\lib\idlelib\Percolator.py", line 25, in insert
self.top.insert(index, chars, tags)
File "C:\Python24\lib\idlelib\PyShell.py", line 315, in insert
UndoDelegator.insert(self, index, chars, tags)
File "C:\Python24\lib\idlelib\UndoDelegator.py", line 81, in insert
self.addcmd(InsertCommand(index, chars, tags))
File "C:\Python24\lib\idlelib\UndoDelegator.py", line 116, in addcmd
cmd.do(self.delegate)
File "C:\Python24\lib\idlelib\UndoDelegator.py", line 216, in do
if text.compare(self.index1, ">", "end-1c"):
File "C:\Python24\lib\lib-tk\Tkinter.py", line 2784, in compare
return self.tk.getboolean(self.tk.call(
TclError: expected boolean value but got ""
Is python threading just not stable or am I doing something grossly wrong? The example came from : http://www.saltycrane.com/blog/2008/09/simplistic-python-thread-example/

It sounds like a bug in IDLE, not a problem with Python. The error is coming from Tkinter, which is a Python GUI toolkit, and which IDLE probably uses. I would report it to whoever maintains IDLE.

Not everything runs properly under IDLE. This is because IDLE is a Python program in itself and has its own attributes and state that can sometimes get messed up by your own code. You can tell this is a problem with IDLE because you can see idlelib in the call stack. Also, you're not using TCL/TK at all in your application, but IDLE is, and the call stack shows that too.
I would advise switching to a more 'inert' text editor for working with Python code!

Related

Pyperclip: "When using gi.repository you must not import static modules like "gobject"

I am making a program that will allow my phone to share its clipboard with my PC. I am using Pyperclip as it appears to be the easiest and most cross-platform solution. However, when I run the code below:
...
elif "incoming_clipboard:" in server_command:
print(server_command)
pyperclip.copy(server_command.replace("incoming_clipboard: ", ""))
...
I get the error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.9/threading.py", line 973, in _bootstrap_inner
self.run()
File "/usr/lib/python3.9/threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "/home/chris/Documents/Programming/Synchrony/Desktop/Phone.py", line 30, in do_sync
self.handle_commands(bluetooth_socket)
File "/home/chris/Documents/Programming/Synchrony/Desktop/Phone.py", line 65, in handle_commands
pyperclip.copy(server_command.replace("incoming_clipboard: ", ""))
File "/usr/lib/python3.9/site-packages/pyperclip/__init__.py", line 659, in lazy_load_stub_copy
return copy(text)
File "/usr/lib/python3.9/site-packages/pyperclip/__init__.py", line 158, in copy_gtk
cb = gtk.Clipboard()
File "/usr/lib/python3.9/site-packages/gi/__init__.py", line 69, in __getattr__
raise AttributeError(_static_binding_error)
AttributeError: When using gi.repository you must not import static modules like "gobject". Please change all occurrences of "import gobject" to "from gi.repository import GObject". See: https://bugzilla.gnome.org/show_bug.cgi?id=709183
I know its not due to the string being invalid or anything, because 1) I am explicitly converting it from bytes to a string, and 2) it prints perfectly fine. I don't know if this is relevant, but I am using Linux, so perhaps that is affecting Pyperclip?
Do you guys have any solutions?
https://github.com/dynobo/normcap/issues/100
After going to the Github page for PyperClip, I found a similar issue that someone else had that suggested switching to PyClip. After installing PyClip and implementing it in project, I can confirm that it works perfectly without any issues.

KeyboardInterrupt Exception

I'm having a hard time handling Exceptions in pycharm 3.8:
When I press ctrl+c running my program, it doesn't work, so I've been told to use pycharm console to test it, and it does work, interrupting the keyboard input.
def readFloat(msg):
while True:
try:
return float(input(f'{msg}'))
except (ValueError, TypeError):
print(f'\033[31mError. Not valid.\033[m')
continue
except KeyboardInterrupt:
print('\033[31mYou didn\'t type a number.\033[m')
return 0
b = readFloat('Your Number: ')
print(f'\nThat\'s your number: {b}')
But now, when I try to Control+C, it doesn't catch my except and print my custom error report, returning 0. It gives me some huge and red error lines:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/User/PycharmProjects/Curso/Aula 23/ex113.py", line 35, in <module>
b = readFloat('Your Number: ')
File "C:/Users/User/PycharmProjects/Curso/Aula 23/ex113.py", line 26, in readFloat
return float(input(f'{msg}'))
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\pydev\_pydev_bundle\pydev_stdin.py", line 64, in readline
requested_input = self.rpc_client.requestInput()
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\pydev\_pydev_comm\pydev_transport.py", line 226, in _req
return super(TSyncClient, self)._req(_api, *args, **kwargs)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\third_party\thriftpy\_shaded_thriftpy\thrift.py", line 160, in _req
return self._recv(_api)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\third_party\thriftpy\_shaded_thriftpy\thrift.py", line 192, in _recv
raise v
console_thrift.KeyboardInterruptException: KeyboardInterruptException()
So I tried to add a generic exception just to print the error class, and I got this:
Error found: <class 'console_thrift.KeyboardInterruptException'>
So I can't manage to detect an except keyboardInterrupt and work with it, just using a generic exception, any ideas?
Edit
The only plugin that I added was a Theme UI to run pycharm totally black, the rest of them came with the instalation, I think. I ran the .py file using CMD and it works just fine, detecting the keyboard interrupt.
Try this:
try:
from console_thrift import KeyboardInterruptException as KeyboardInterrupt
except ImportError:
pass
Ref: Why doesn't this python keyboard interrupt work? (in pycharm)
The thing about IDEs is that they are not quite the same as running normally, especially when it comes to handling of keyboard characters. The way you press ctrl-c, your IDE thinks you want to copy text. The python program never sees the character. Perhaps it brings up a separate window when running? Then you would select that window before ctrl-c.

Thread._wait_for_tstate_lock() never returns

My program appears to run in a deadlock sometimes when I hit Ctrl+C. I'm trying to catch the keyboard interrupt and gracefully stop all running threads, but I'm not quite there yet.
I'm using a concurrent.futures.ThreadPoolExecutor. To find the location of the deadlock, I'm using the this receipe from ActiveState.
Now, here's the full stacktrace:
# ThreadID: 4856
File: "c:\users\niklas\appdata\local\programs\python\python36\lib\threading.py", line 884, in _bootstrap
self._bootstrap_inner()
File: "c:\users\niklas\appdata\local\programs\python\python36\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File: "C:\Users\niklas\repos\nodepy\craftr\lib\utils\tracer.py", line 66, in run
self.stacktraces()
File: "C:\Users\niklas\repos\nodepy\craftr\lib\utils\tracer.py", line 80, in stacktraces
fout.write(stacktraces())
File: "C:\Users\niklas\repos\nodepy\craftr\lib\utils\tracer.py", line 28, in stacktraces
for filename, lineno, name, line in traceback.extract_stack(stack):
# ThreadID: 6068
File: "c:\users\niklas\appdata\local\programs\python\python36\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File: "c:\users\niklas\appdata\local\programs\python\python36\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File: "C:\Users\niklas\repos\nodepy\craftr\.nodepy_modules\.bin\craftr.exe\__main__.py", line 9, in <module>
sys.exit(nodepy.main.main())
File: "c:\users\niklas\repos\nodepy\nodepy\nodepy\main.py", line 103, in main
ctx.load_module(ctx.main_module, do_init=False)
File: "c:\users\niklas\repos\nodepy\nodepy\nodepy\context.py", line 253, in load_module
module.load()
File: "c:\users\niklas\repos\nodepy\nodepy\nodepy\loader.py", line 43, in load
exec(code, vars(self.namespace))
File: "C:\Users\niklas\repos\nodepy\craftr\lib\main.py", line 110, in <module>
sys.exit(main())
File: "C:\Users\niklas\repos\nodepy\craftr\lib\main.py", line 106, in main
return backend.build_main(backend_args, session, module)
File: "C:\Users\niklas\repos\nodepy\craftr\lib\build_backends\default.py", line 194, in build_main
executor.run(actions)
File: "C:\Users\niklas\repos\nodepy\craftr\lib\build_backends\default.py", line 171, in run
self.wait()
File: "C:\Users\niklas\repos\nodepy\craftr\lib\build_backends\default.py", line 137, in wait
self.pool.shutdown(wait=True)
File: "c:\users\niklas\appdata\local\programs\python\python36\lib\concurrent\futures\thread.py", line 144, in shutdown
t.join()
File: "c:\users\niklas\appdata\local\programs\python\python36\lib\threading.py", line 1056, in join
self._wait_for_tstate_lock()
File: "c:\users\niklas\appdata\local\programs\python\python36\lib\threading.py", line 1072, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
I can't make sense from this traceback. It appears that Thread._wait_for_tstate_lock() never returns (I checked multiple times, it always hangs at that line). There is no thread running other than the main thread (6068) and the tracer thread (4856).
I don't quite understand the implementation details of threading.Thread. What could cause Thread._tstate_lock.acquire() to block indefinitely?
Update 2017/11/07 -- 01:45am CEWT
This seems to happen when pool.shutdown() is called multiple times...
I'm not 100% certain it's the reason you're seeing this as you are using Windows, but I encountered this on Linux with Python 3.6 in a similar scenario.
I was using .shutdown() on a concurrent.futures.ThreadPoolExecutor and the program would seem to hang up.
Sometimes it would finally exit after 30-60 seconds.
Ctrl-C always resulted in a traceback showing it was sitting in _wait_for_tstate_lock()
Note: in Python 3 a second Ctrl-C actually exits
My problem occurred when the function submitted was using time.sleep() in a loop.
Looking at the HtmlFileTracer implementation in current nodepy code on github I see a similar scenario to what I was doing, (continuously loop and sleep for an interval unless some sort of flag was set)

RuntimeError on Windows trying to run a simple program

I have this simple program:
from PIL import Image
import pyscreenshot as ImageGrab
print "hi"
im=ImageGrab.grab()
im.show()
This works perfectly fine on Ubuntu, but it gives the following error on Windows:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Python27\lib\multiprocessing\forking.py", line 380, in main
prepare(preparation_data)
File "C:\Python27\lib\multiprocessing\forking.py", line 509, in prepare
'__parents_main__', file, path_name, etc
File "C:\Users\Administrator\Downloads\sample.py", line 5, in <module>
im=ImageGrab.grab()
File "C:\Python27\lib\site-packages\pyscreenshot\__init__.py", line 46, in gra
b
return _grab(to_file=False, childprocess=childprocess, backend=backend, bbox
=bbox)
File "C:\Python27\lib\site-packages\pyscreenshot\__init__.py", line 29, in _gr
ab
return run_in_childprocess(_grab_simple, imcodec.codec, to_file, backend, bb
ox, filename)
File "C:\Python27\lib\site-packages\pyscreenshot\procutil.py", line 28, in run
_in_childprocess
p.start()
File "C:\Python27\lib\multiprocessing\process.py", line 130, in start
self._popen = Popen(self)
File "C:\Python27\lib\multiprocessing\forking.py", line 258, in __init__
cmd = get_command_line() + [rhandle]
File "C:\Python27\lib\multiprocessing\forking.py", line 358, in get_command_li
ne
is not going to be frozen to produce a Windows executable.''')
RuntimeError:
Attempt to start a new process before the current process
has finished its bootstrapping phase.
This probably means that you are on Windows and you have
forgotten to use the proper idiom in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce a Windows executable.
There is no multiprocessing. I saw some other answers, but they did not help.
Can some please suggest a possible problem here?
There's a known problem with the multiprocessing module on Windows (to elaborate on roganosh remark): using multiprocessing module must be done in a function or in the __main__ section (after all the imports are initialized), not in the root of the script because of the way Windows spawns the python executable (hence the "bootstrap phase" error). No issue on Linux. Looks very much like the same issue as RuntimeError on windows trying python multiprocessing.
Try changing into this code:
from PIL import Image
import pyscreenshot as ImageGrab
if __name__ == "__main__":
im=ImageGrab.grab()
im.show()
The traceback indicates that there is multiprocessing being used in the background, not explicitly in your own code. Specifically, it is being called by pyscreenshot\procutil.py. The relevant lines of the traceback:
File "C:\Python27\lib\site-packages\pyscreenshot\procutil.py", line 28, in run
_in_childprocess
p.start()
File "C:\Python27\lib\multiprocessing\process.py", line 130, in start
self._popen = Popen(self)
Since the issue is in the library, there would be nothing you could do except modify the library yourself. However, this page says that pyscreenshot is a "Replacement for the ImageGrab Module, which works on Windows only". So instead, you should install ImageGrab library, which seems to do exactly the same thing, but is only compatible with Windows and MacOS (see here)

How launch a function in a new thread without locking the main program in python?

I'm trying to launch a function in a new thread because the function makes something not related to the main program.
I tried to do this with multiprocessing module as:
import multiprocessing
import time
def mp_worker(a):
#time.sleep(a)
print('a:' +str(a))
return
for k in range(5):
p = multiprocessing.Process(target= mp_worker , args=(k,))
p.start()
print('keep going :' + str(k))
But I have a bunch of error:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 106, in spawn_main
exitcode = _main(fd)
File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 115, in _main
prepare(preparation_data)
File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 226, in prepare
_fixup_main_from_path(data['init_main_from_path'])
File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 278, in _fixup_main_from_path
run_name="__mp_main__")
File "C:\Anaconda3\lib\runpy.py", line 254, in run_path
pkg_name=pkg_name, script_name=fname)
File "C:\Anaconda3\lib\runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "C:\Anaconda3\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\Maxime\PycharmProjects\NeuralMassModelSofware_Pyqt5\dj.py", line 14, in <module>
p.start()
File "C:\Anaconda3\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Anaconda3\lib\multiprocessing\context.py", line 212, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Anaconda3\lib\multiprocessing\context.py", line 313, in _Popen
return Popen(process_obj)
File "C:\Anaconda3\lib\multiprocessing\popen_spawn_win32.py", line 34, in __init__
prep_data = spawn.get_preparation_data(process_obj._name)
File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 144, in get_preparation_data
_check_not_importing_main()
File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 137, in _check_not_importing_main
is not going to be frozen to produce an executable.''')
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
Someone knows how I can launch whatever function I want in a new thread and be sure that the main program is still running normally? I'm a little lost with multiprocessing, I admit that :)
I aim to launch some displays (graphical or print I don't know yet) for the user in new threads without interrupting the main program.
What you are doing isn't multithreading, it's muliprocessing.
Change.
multiprocessing.Process(...
with.
threading.Thread(...
Python ยป 3.6.1 Documentation: threading.Thread
SO Q&A: multiprocessing-vs-threading-python
Beside this, you can overcome the Error adding a time.sleep(0.2)after start(...
This is what I am getting when running the code you have provided:
python3.6 -u "multiprocessingError_Cg.py"
keep going :0
a:0
keep going :1
keep going :2
a:1
a:2
keep going :3
keep going :4
a:3
a:4
>Exit code: 0
So the answer to your question is that you have to look for the cause of the trouble with multiprocessing elsewhere, but not in the section of code listed in your question.
Take a close look at what was provided in answers and comments here - maybe it could help also in your case?
Here what was said in comments to one of the answers there:
Dave: Would this work if beBusyFor (in your case mp_worker) uses multiprocessing internally?
#Dave just try it out and report back here if it worked. Haven't tested such a case yet, so my opinion that it should work leaving some mess of processes with no parents doesn't matter here and therefore shouldn't be taken in consideration.
Dave: **No cigar ending child processes unfortunately** :(

Categories