-1

I have 4 thread that reading from 4 text files and additional thread to write that 4 threads already read , I used the Queue, So How I can use semaphore or mutex lock?

  • Code Run with Queue:

    import queue
    import threading
    from datetime import datetime
    
    start_time = datetime.now()
    
    def print_text(q, filename):
        for line in open(filename, encoding="utf8"):
            q.put(line.strip())
        q.put('--end--')
    
    def print_result(q, count=0):
        while count:
            line = q.get()
            if line == '--end--':
                count -= 1
            else:
                print(line)
    
    if __name__ == "__main__":
        filenames = ['file_1.txt', 'file_2.txt', 'file_3.txt', 'file_4.txt']
        q = queue.Queue()
        threads = [threading.Thread(target=print_text, args=(q, filename)) for filename in filenames]
        threads.append( threading.Thread(target=print_result, args=(q, len(filenames))) )
        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()
    time_elapsed = datetime.now() - start_time
    print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))
    
  • My attempt to solved by Mutex Lock:

    import threading
    import time
    import random
    
    mutex = threading.Lock()
    class thread_one(threading.Thread):
        def run(self):
            global mutex
            print ("The first thread is now sleeping")
            time.sleep(random.randint(1, 5))
            print("First thread is finished")
            mutex.release()
    
    class thread_two(threading.Thread):
        def run(self):
            global mutex
            print ("The second thread is now sleeping")
            time.sleep(random.randint(1, 5))
            mutex.acquire()
            print("Second thread is finished")
    
    class thread_three(threading.Thread):
        def run(self):
            global mutex
            print ("The Three thread is now sleeping")
            time.sleep(random.randint(1, 5))
            mutex.acquire()
            print("Three thread is finished")
    
    class thread_four(threading.Thread):
        def run(self):
            global mutex
            print ("The Four thread is now sleeping")
            time.sleep(random.randint(1, 5))
            mutex.acquire()
            print("Four thread is finished")
    
    mutex.acquire()
    t1 = thread_one()
    t2 = thread_two()
    t3 = thread_three()
    t4 = thread_four()
    t1.start()
    t2.start()
    t3.start()
    t4.start()
    
martineau
  • 119,623
  • 25
  • 170
  • 301
  • I never think Stack as a free code , but I already try many times to solve the problems in different methods and I appreciate everyone help me with idea or helping me to write the code, I a beginner in Programming. I will share my attempts to solve the issue – Badr Khaled Jan 09 '22 at 15:07
  • @martineau, its not as straight forward as you narrate it. If you type in "what have you tried?" as comment, SO won't let you post it. Instead, you get this messages in red. *Comments cannot contain that content. If the author didn't show what was tried, why do you assume they tried anything? Either ask for a specific bit of information, suggest a specific improvement, or downvote and move on.* This implies that the asker does not have to try anything nor prove it. – The Fool Jan 09 '22 at 15:18
  • @Ali: That's a good update except you didn't say what's wrong with your attempt. – martineau Jan 09 '22 at 15:20
  • @martineau Because you didnt use the exact phrasing that triggeres the message. And still, you are insisiting on points which are adressed in that message. – The Fool Jan 09 '22 at 15:22
  • Mr. @martineau , I try as a beginner to solve the problem , the problem is I can not pass the text file to my solution – Badr Khaled Jan 09 '22 at 15:24
  • @Ali: I understand your question — never claimed I didn't. I would answer now, but I can't run it because I don't have pandas installed (i.e. your code isn't a [mre] since it has stuff in it completely unrelated to the issue). – martineau Jan 09 '22 at 15:26
  • Can I share my note to show my effort to try to solve the problem: https://drive.google.com/file/d/14wsPWd8yJz35oK4p_cZRM78BfExbkkdh/view?usp=sharing – Badr Khaled Jan 09 '22 at 15:29
  • Links to off-site resources are discourage here (mainly because they tend to disappear eventually). Besides seeing it isn't necessary when you can put the code right in your question as you now have. Just be patient, someone is much more likely to answer it now. – martineau Jan 09 '22 at 15:32
  • Thanks for you understanding MR.@martineau – Badr Khaled Jan 09 '22 at 15:33
  • @Fool: Feel free to flag my comment if you feel it was inappropriate. I'm merely trying to instruct the OP on how to post questions that are more likely to get answered. – martineau Jan 09 '22 at 15:42
  • @Fool , Did I need to edit my question or it's clear now. – Badr Khaled Jan 09 '22 at 18:28
  • @Ali: The code you claim is using a [`Queue`](https://docs.python.org/3/library/queue.html#queue.Queue) isn't. – martineau Jan 10 '22 at 01:37
  • @martineau Yes Sir, – Badr Khaled Jan 11 '22 at 02:15
  • @martineau Yes Sir, But i want to replace the queue with Semaphore or Mutex Lock. I suppose that it will return to beginning : 4 threads readimg feom 4 text files and 1 thread write from the 4 thread in the same time and save into a new text file, and here we got the thread issue that saving it will randomly, So we used the queue to fix it and it works, But now I want to try Semaphore or Mutex Lock. – Badr Khaled Jan 11 '22 at 02:21
  • My point was there is **no** `Queue` to replace. If you are talking about the variable `threads`, it is a **`list`**. Regardless, a lock or mutex is used to synchronize access to resources when there are multiple threads of execution trying to use them at the same time. In your examples the only thing like that is printing things to the screen, so the outputs of the threads will be intermingled @Tim Roberts [already explained this to you](https://stackoverflow.com/questions/70546551/i-have-an-issue-reading-multiple-text-files-using-multi-threading-by-python#comment124706883_70546551). – martineau Jan 11 '22 at 09:09
  • @martineau Yes Sir, the main problem with 4 threads reading and 1 thread writing, the output will be mixed as Tim Roberts is explain to me before, I will update the new code now that had a queue. – Badr Khaled Jan 11 '22 at 14:42
  • Your question senseless. A Queue is a [data structure](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) and a Mutex is a [synchronization tool](https://en.wikipedia.org/wiki/Lock_(computer_science). You can't replace one with the other. It's equivalent to wanting to know how to replace a truck with a traffic-light. – martineau Jan 11 '22 at 18:16
  • @martineau My point is the queue is used to fix the thread output issue through every thread starting must be done and next one will run till the the end "FIFO", Mutex Lock and semaphore is controlling of access the resource when I have many threads working in the same time. – Badr Khaled Jan 11 '22 at 21:15

1 Answers1

0
import queue                    
import threading                

s = threading.Semaphore(5)
def print_text(s, q, filenames):
    with s:
        for line in open(filenames, encoding="utf8"):
            q.put(line.strip())
        q.put('--end--')

def print_result(q, count=0):   
    while count:                
        line = q.get()          
        if line == '--end--':   
            count -= 1          
        else:
            print(line)

if __name__ == "__main__":
    filenames = ['file_1.txt', 'file_2.txt', 'file_3.txt', 'file_4.txt']

    q = queue.Queue()    

    threads = [threading.Thread(target=print_text, args=(s, q, filename)) for filename in filenames]
    
    threads.append( threading.Thread(target=print_result, args=(q, len(filenames))) ) 

    for thread in threads:
        thread.start()
    
    for thread in threads:
        thread.join()