Search code examples
multithreadingpython-3.xthread-synchronization

Synchronize two functions into separate classes


In a class there are different functions. In a separate file in another class I want to catch the messages and print to gui. As a simulation I have the following code:

import threading
import time
import logging

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',)

message = None


def messages_generator(condition):
    global message
    with condition:
        logging.debug('Condition: {}'.format(condition))
        for i in range(5):
            message = 'i = ' + str(i)
            time.sleep(1)
            logging.debug('Condition wait')
            condition.wait()


def messages_sow(condition):
    global message
    with condition:
        print(message)
        logging.debug('Condition notify')
        condition.notify()
    logging.debug('Tread finished')


condition = threading.Condition()
messages_generator_thread = threading.Thread(name='Message Generator', target=messages_generator, args=(condition,))
messages_sow_thread = threading.Thread(name='Message Sow', target=messages_sow, args=(condition,))

messages_generator_thread.start()
messages_sow_thread.start()

What I want is the messages_generator to wait for the message to be printed by the messages_sow emphasized text and continue until it is completed. When I run the above code, the program freezes on the second 'Condition wait'. Any advice to be welcomed.


Solution

  • I finally managed to work the code above, but not on the basic program which I develop based on the Model - View - Controller programming model. I quote the code that works.

    import threading
    import time
    import logging
    
    logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',)
    
    message = None
    
    
    def messages_generator(condition):
        logging.debug('--- Start ---')
        global message
        messages_number = 5
        for i in range(messages_number):
            logging.debug('Inside For. i = {}'.format(i))
            condition.acquire()
            if message is not None:
                logging.debug('Condition wait')
                condition.wait()
            if i == (messages_number - 1):
                message = 'end'
                logging.debug('Message = {}'.format(message))
            else:
                message = 'i = ' + str(i)
                time.sleep(1)
            logging.debug('Condition notify')
            condition.notify()
            logging.debug('Condition release')
            condition.release()
    
    def messages_sow(condition):
        logging.debug('--- Start ---')
        global message
        while True:
            logging.debug('Inside While. stop = {}'.format(True))
            condition.acquire()
            if message is None:
                logging.debug('Condition wait')
                condition.wait()
            else:
                print(message)
            if message == 'end':
                break
            message = None
    
            condition.notify()
            condition.release()
        logging.debug('Tread finished')
    
    
    condition = threading.Condition()
    messages_generator_thread = threading.Thread(name='Message Generator', target=messages_generator, args=(condition,))
    messages_sow_thread = threading.Thread(name='Message Sow', target=messages_sow, args=(condition,))
    
    messages_generator_thread.start()
    messages_sow_thread.start()