I haven't used threading in python yet and I'm trying to get a working example going but it doesn't seem to be working. Once my first thread begins my program just hangs while that "thread" does it's work. It appears to be acting as if I just called a function normally. My second thread which is setup to run alongside thread1 doesn't start until thread1 finishes. Is there something I'm doing wrong?
class MainDialog(QDialog, Gui.Ui_Dialog):
def __init__(self,parent=None):
super(MainDialog,self).__init__(parent)
self.setupUi(self)
threading.Thread(target=thread1()).start()
threading.Thread(target=thread2()).start()
def thread1(self):
//Do stuff
def thread2(self):
//Do other stuff
Related
I have the following function:
def send_command(self, cmd):
self.loop.call_soon_threadsafe(
functools.partial(
self._transport.write, str(cmd).encode() + b"\n"
)
)
The system under test (sut) is a class inheriting from asyncio.Protocol which sends some commands to a piece of hardware on a socket. I have to use threads since this is part of a GUI under wxPython. Finally, if I call self._transport.write the code works fine on Linux but crashes on Windows™.
When running the test:
#pytest.mark.asyncio
async def test_send_command(self):
self.sut._transport = Mock()
self.sut.send_command("ook eek")
assert self.sut._transport.write.called is True
I get an assert error. The self.sut._transport.write is never called. If I call self._transport.write directly in the function, the code crashes on Windows™ but the test passes just fine.
What am I missing here?
Anyone?…
Surely, this is not such an edge case…
A work around…
After reading and experimenting with even loops, using this:
import asyncio
import selectors
selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)
by passes the problem. Of course, it means using a sub-efficient loop on Windows. ☹ PHA!
Anyone with a better solution is welcome to some fake internet points.
So I found this gist on how to create a "thread pooling" system and my issue is: when the executed function finished in the thread the "completed" signal must be emitted from (or to) the main thread. The solution presented on the gist was to overwrite GObject.emit function using GObject.idle_add(GObject.GObject.emit, self, *args) which does the trick in the gist example, but misteriously does not work for me. I created a slightly modified version of his code that does what I need, except from emitting the signals correctly/at all.
class _IdleObject(GObject.GObject):
""" Override GObject.GObject to always emit signals in the main thread by
emmitting on an idle handler """
#trace
def __init__(self):
GObject.GObject.__init__(self)
#trace
def emit(self, *args):
GLib.idle_add(GObject.GObject.emit, self, *args)
In summary, the signals are either not emitted or emitted on secondary threads (when the emit function overwrite is commented out) which can't update the UI therefore don't solve my problem. Any ideas on what's going on?
My version of his gist can be found here
I'm trying to develop a GDB python extension that defines a command that launches a new thread, in which the user can inspect an arbitrary type of variables. The skeleton of my python extension is this:
import gdb
import threading
def plot_thread():
import time
while True:
print('Placeholder for a window event loop.')
time.sleep(1)
pass
pass
class PlotterCommand(gdb.Command):
def __init__(self):
super(PlotterCommand, self).__init__("plot",
gdb.COMMAND_DATA,
gdb.COMPLETE_SYMBOL)
self.dont_repeat()
pass
def invoke(self, arg, from_tty):
plot_thread_instance=threading.Thread(target=plot_thread)
plot_thread_instance.daemon=True
plot_thread_instance.start()
pass
pass
PlotterCommand()
As can be seen, I define a plot command here. When I try to debug the following program, GDB will hang if I:
Put a breakpoint anywhere inside the procedure() thread (say, line 9, inside the while loop).
Run the command plot after gdb hits the breakpoint.
Run continue after that.
#include <iostream>
#include <thread>
using namespace std;
void procedure() {
cout << "before loop"<<endl;
while(1) {
cout << "loop iteration"<<endl;
}
}
int main() {
thread t(procedure);
t.join();
return 0;
}
The strangest thing is that, if I change this code to call procedure() without launching a thread, GDB never hangs (and the placeholder messages are still printed as I expect).
So far, I've tried to run this procedure with GDB versions 7.5.1 and 7.10, but I always experience the same behavior.
What am I doing wrong? Aren't daemon threads not supported by GDB? That doesn't seem to be in accordance with what the section 23.2.2.1 of the documentation is suggesting: GDB may not be thread safe, but I don't think it should hang after launching such a silly daemon thread.
From this blog post:
GDB uses this function (sigsuspend, the function where GDB hangs) to wait for new events from the application execution: when something occurs in the debuggee (see how debuggers work), the kernel will inform GDB of it by sending a SIGCHLD signal. When it's received, GDB awakes and check what happened.
However, the signal is delivered to GDB process, but not necessarily to its main thread. And it practise, it occurs often that it's delivered to the second thread, who doesn't care about it (that's the default behavior), and continues its life as if nothing occurred.
The solution is to configure the thread signal handling behavior, so that only the GDB main thread gets notified by these signals:
import gdb
import threading
import pysigset, signal # Import these packages!
def plot_thread():
import time
while True:
print('Placeholder for a window event loop.')
time.sleep(1)
pass
pass
class PlotterCommand(gdb.Command):
def __init__(self):
super(PlotterCommand, self).__init__("plot",
gdb.COMMAND_DATA,
gdb.COMPLETE_SYMBOL)
self.dont_repeat()
pass
def invoke(self, arg, from_tty):
with pysigset.suspended_signals(signal.SIGCHLD): # Disable signals here!
plot_thread_instance=threading.Thread(target=plot_thread)
plot_thread_instance.daemon=True
plot_thread_instance.start()
pass
pass
pass
PlotterCommand()
The pysigset package is required, and can be installed from pip (sudo pip install pysigset).
Problem Description:
A server process which keeps a database (Cacheable)
A client which reads and displays the data in UI (RemoteCache)
They talk to each other through Twisted PB
I'd like to refresh my UI when the server database changes.
My client has a method, _mutation_handler, which is notified by the server
To notify my UI, I created a singleton Notifier class which emits a signal.
Then in my Qt widget, I wire the signal to the widget's slot.
# inside the RemoteCache subclass on my client
# notified by the PB server when something happens
def __mutation_handler(self):
notifier = Notifier()
notifier.notify()
# inside notify.py
class Notifier(QObject):
def __new__(cls):
# Make it a singleton
def notify(self):
self.emit(SIGNAL('SomethingChanged'))
# inside the RemoteCache subclass on my client
def __mutation_handler(self):
# singleton notifier
notifier = Notifier()
notifier.notify()
# inside my widget.py
class MyWidget(QWidget):
def __init__(self):
... # code
self.notifier = Notifier()
self._create_signal_slot_connections()
... # more code
def _create_signal_slot_connections(self):
self.connect(self.notifier, SIGNAL('SomethingChanged'),self.shout)
def shout(self):
print 'Server's database changed!!!'
Problem:
When I change something in my server's database, _mutation_handler gets called
correctly, then the signal is emitted alright.
However, MyWidget is NOT able to catch the signal.
Note: I am using qt4reactor to adapt Twisted's event loop to suit qt's
I really appreciate your help!!!
There seems to be a new API for signals in PyQt4. See http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/new_style_signals_slots.html for examples on its use. Perhaps this will work better.
I'm using Swing from Jython, and I found that while System.exit() (from java.lang) or JFrame.setDefaultCloseOperation(EXIT_ON_CLOSE) work properly, calling sys.exit() hangs.
Apparently, a function is registered through atexit.register that waits for all threads to exit, as it is expected from Python (this is actually different from Java).
This means that if an ActionListener gets called (for instance when clicking on a JButton), AWT's Event Dispatching Thread gets spawned, and calling sys.exit() will hang forever, waiting for it to exit.
Here is an example: https://gist.github.com/2877919. Closing the frame exits the program, unless the button is clicked first.
What is the best way to exit my Jython application? Using EXIT_ON_CLOSE or System.exit() would completely ignore atexit...
I don't think you need multithreading for this, you just need to make sure the window is not closed until you want so. When you close the window, you close the system:
from javax.swing import JFrame, JButton, JOptionPane
from java.awt.event import ActionListener, WindowAdapter
import sys
class Frame(JFrame, ActionListener):
def __init__(self):
self.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE)
button = JButton("Hello", actionCommand='button')
button.addActionListener(self)
self.getContentPane().add(button)
self.pack()
self.setResizable(False)
def actionPerformed(self, event):
print event.getActionCommand();
class Adapter(WindowAdapter):
def windowClosing(self, event):
if JOptionPane.showConfirmDialog(None, "Wanna exit?","Jython Test", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION:
sys.exit(0)
if __name__ == '__main__':
frame = Frame();
frame.setVisible(True)
frame.addWindowListener(Adapter())