kerz
kerz

Reputation: 69

How to use QMutex correctly with QThread?

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


import time
import sys
import numpy as np

       

class Mainthread(QThread):

    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        self.running = None
        self.mutex = QMutex()



    def run(self):
                   
        while self.running:
            self.mutex.lock()
            print ("test")
            time.sleep(1)

            self.mutex.unlock()
                                                

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()


        self.mainthread = Mainthread(self)
        self.mainthread.running = True
        self.mainthread.start()

        self.mainthread1 = Mainthread(self)
        self.mainthread1.running = True
        self.mainthread1.start()



    
app = QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()
app.exec_()

I have this code where I run two instances of the same MainThread class.

What I was expecting was that mainthread's message (which is "test") would print, then wait for a sec and then mainthread1's would be printed. Instead, it seems like both threads are running at the same time. Is there something I'm missing?

Upvotes: 3

Views: 825

Answers (1)

CrazyChucky
CrazyChucky

Reputation: 3518

In your code, each thread creates its own separate mutex, so no relation is enforced between the two. Create a single mutex first, and pass it to the threads.

I've added to the test print to identify which thread is doing it.

import time
import sys

from PyQt5.QtCore import QThread, QMutex
from PyQt5.QtWidgets import QMainWindow, QApplication


class Mainthread(QThread):
    def __init__(self, mutex, parent, suffix=""):
        super().__init__(parent)
        self.parent = parent
        self.running = None
        self.mutex = mutex
        self.suffix = suffix

    def run(self):  
        while self.running:
            self.mutex.lock()
            print (f"Test from mainthread{self.suffix}")
            time.sleep(1)

            self.mutex.unlock()


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        mutex = QMutex()

        self.mainthread = Mainthread(mutex, self)
        self.mainthread.running = True
        self.mainthread.start()

        self.mainthread1 = Mainthread(mutex, self, "1")
        self.mainthread1.running = True
        self.mainthread1.start()


app = QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()
app.exec_()

Note: I don't have PyQt5 installed (and doing so on my architecture is tricky), but I tested this in PySide6 and as far as I know the behavior should be consistent.

Upvotes: 2

Related Questions