0

I am planning a PySide Project which has a user authentication. Some of the operations of the program will require threads in order to keep the GUI responsive. Some of the operations which are done inside the threads require the user id or some other user data.

The main question is how to make those data available for the threads. The threads will not change the user id and there are only reading operations on the given user data.

The code below is a very simple mock up to illustrate the problem. The User class returns the user data if the login was successful. They will be stored as class variable inside the Interface class. As soon the Thread/QRunnable is initialized the user data are given to the worker and stored as class variable for the lifetime of the thread.

I couldn't find any clear answer to:

  • Is reading the variable inside the thread "thread safe" (As reading from a dict is an atomic operation it should be)

  • Is there a better way to make data like this available to a bigger project? e.g. Config files, User data...

Simple example:

from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtCore import QObject, QRunnable, QThreadPool


class Worker(QRunnable):

    def __init__(self, current_user):
        super().__init__()
        self.current_user = current_user

    def run(self) -> None:
        print(self.current_user)

class User():

    def login(self, user: str, password: str):
        return {'user_id': 1, 'user_name': f'{user}'}

class Interface(QMainWindow):

    def __init__(self):
        super().__init__()
        self.thread_pool = QThreadPool.globalInstance()
        self.user = User()

        self.current_user = self.user.login('John Doe', '123456')

        worker = Worker(self.current_user)
        self.thread_pool.start(worker)
        self.show()


if __name__ == '__main__':
    app = QApplication([])
    interface = Interface()
    app.exec()

The ID of the user data stays always the same so all workers will operate on the same memory space as far as I understood

  • Purely read-only access is fine. Does this answer your question? https://stackoverflow.com/questions/3358770/python-dictionary-is-thread-safe/3358974#3358974 As for using a different mechanism, sounds like you just want some global variables or a shared "Context" object – Homer512 Jan 24 '23 at 07:59
  • Thanks, it answers the question about the thread safeness. It would be interesting for me how this can be handled in a different way as well and how other programmers would tackle this kind of problem. A context object would be nice to have. I thought about creating a temporary QSettings Object which will hold those data – Georg Stricker Jan 24 '23 at 08:10
  • Every `QSettings` object shares the same backing store unless you set different constructor arguments, and they are always saved to disk. I don't think that is appropriate for something that may contain a password or could otherwise be used to capture communication. – Homer512 Jan 24 '23 at 08:13
  • Last question :-) Would it be safe to create a python dataclass with the user data and move it to the thread. In this case the thread would read from the instance variables of the dataclass. As long there only read operations this should be safe as well, am I right? – Georg Stricker Jan 24 '23 at 08:23
  • Object attributes are simply stored in a dictionary in python, so the same principle applies. As long as no one is changing the attributes, multiple threads can read them simultaneously and threads can always share the object. Once you start adding options to change attributes (e.g. the user setting a different login), you have to look more closely at synchronization e.g. adding a mutex, but that depends on the exact access pattern – Homer512 Jan 24 '23 at 08:34
  • Thanks help for clarification. The will be no change on the data so I will go for a dataclass to encapsulate the data. Seems for me the most readable and maintainable solution – Georg Stricker Jan 24 '23 at 08:38

0 Answers0