python DAY_12 parallel programming

Learning content:
1. _threadmodule
2.threading module
3. Synchronization lock
4.qunue Queue
A key
1. _threadModule is used differently from other modules
_indicates that python is no longer recommended, but this command is used for basic learning

import time
import _thread


def work(n):
    print(f'The program starts at:{time.ctime()}')
    time.sleep(n)
    print("The program ends at:{}".format(time.ctime()))


def main():
    print(f'The main program starts at:{time.ctime()}')
    _thread.start_new(work, (5,))
    _thread.start_new(work, (2,))
    time.sleep(7)
    print(f"The main program ends at:{time.ctime()}")


if __name__ == "__main__":
    main()

Note that _thread.start_new(work, (2,)) is entered as a tuple!!
give the result as follows

2. Use of threadi module

import time
import _thread
import threading


def work(n):
    print(f'The program starts at:{time.ctime()}')
    time.sleep(n)
    print("The program ends at:{}".format(time.ctime()))


def main():
    print(f'The main program starts at:{time.ctime()}')
    # _thread.start_new(work, (5,))
    # _thread.start_new(work, (2,))
    threads = []
    t1 = threading.Thread(target=work, args=(6,))
    threads.append(t1)
    t2 = threading.Thread(target=work, args=(2,))
    threads.append(t2)
    for s in threads:
        s.start()
    for s in threads:
        s.join()
    # time.sleep(7)
    print(f"The main program ends at:{time.ctime()}")


if __name__ == "__main__":
    main()

s.start() start thread
In the code, we found a directive for s.join(), which is very useful. It synchronizes the thread of the main program with the child thread, and the main thread ends when the child thread ends.
give the result as follows

But there's a drawback here, we don't know the order of threads
The solution is to use the threading.current_thread().name directive with the following code

import time
import _thread
import threading


def work(n):
    print(f'{threading.current_thread().name}The program starts at:{time.ctime()}')
    time.sleep(n)
    print("{}The program ends at:{}".format(threading.current_thread().name, time.ctime()))


def main():
    print(f'The main program starts at:{time.ctime()}')
    # _thread.start_new(work, (5,))
    # _thread.start_new(work, (2,))
    threads = []
    t1 = threading.Thread(target=work, args=(6,))
    threads.append(t1)
    t2 = threading.Thread(target=work, args=(2,))
    threads.append(t2)
    for s in threads:
        s.start()
    for s in threads:
        s.join()
    # time.sleep(7)
    print(f"The main program ends at:{time.ctime()}")


if __name__ == "__main__":
    main()

Write thread s derived classes by yourself to implement functions!!
Helpful for future work and study
The code is as follows

import time
import _thread
import threading


def work(n):
    print(f'{threading.current_thread().name}The program starts at:{time.ctime()}')
    time.sleep(n)
    print("{}The program ends at:{}".format(threading.current_thread().name, time.ctime()))


class Mythread(threading.Thread):  # My definition inherits from threading.Thread
    def __init__(self, fun, args):
        threading.Thread.__init__(self)
        self.fun = fun
        self.args = args

    def run(self):
        self.fun(*self.args)


def main():
    print(f'The main program starts at:{time.ctime()}')
    # _thread.start_new(work, (5,))
    # _thread.start_new(work, (2,))
    threads = []

    # t1 = threading.Thread(target=work, args=(6,))

    t1 = Mythread(work, (4,))

    threads.append(t1)

    # t2 = threading.Thread(target=work, args=(2,))

    t2 = Mythread(work, (2,))
    threads.append(t2)

    for s in threads:
        s.start()
    for s in threads:
        s.join()
    # time.sleep(7)
    print(f"The main program ends at:{time.ctime()}")


if __name__ == "__main__":
    main()

3. Synchronization primitive: lock
Take the order in which you play games for example
Suppose there are currently three game consoles, each of which requires five people to play, assuming they play at the same speed

import time
import threading


play = []


def order_play(n, lst=[]):#Playing order
    for i in range(1, n + 1):
        lst.append(i)


def main():
    thread = []
    for i in range(3):#Create three game consoles
        i = threading.Thread(target=order_play, args=(5, play))#Reference threading operation
        thread.append(i)
    for t in thread:
        t.start()
    for t in thread:
        t.join()
    print(play)


if __name__ == "__main__":
    main()
    

give the result as follows

Everyone plays each game in a certain order, but what happens if we don't play the same time?

import time
import threading
import random

play = []


def order_play(n, lst=[]):
    for i in range(1, n + 1):
        time.sleep(random.randint(0, 3))#Play time is random
        lst.append(i)


def main():
    thread = []
    for i in range(3):
        i = threading.Thread(target=order_play, args=(5, play))
        thread.append(i)
    for t in thread:
        t.start()
    for t in thread:
        t.join()
    print(play)


if __name__ == "__main__":
    main()

give the result as follows

At this point, I introduced locks to normalize the order!

import time
import threading
import random

play = []
lock = threading.Lock()


def order_play(n, lst=[]):
    with lock:
        for i in range(1, n + 1):
           time.sleep(random.randint(0, 3))
           lst.append(i)


def main():
    thread = []
    for i in range(3):
        i = threading.Thread(target=order_play, args=(5, play))
        thread.append(i)
    for t in thread:
        t.start()
    for t in thread:
        t.join()
    print(play)


if __name__ == "__main__":
    main()
lock.acquire()
   for i in range(1, n + 1):
    time.sleep(random.randint(0, 3))
    lst.append(i)
lock.release()

lock comes with threading, so import threading
give the result as follows

4. Queues
FIFO Queue Common Operations

Implementation of FIFO Queue

import time
import queue
import random
import threading


def produce(data_queue):
    for i in range(5):
        time.sleep(1)
        item = random.randint(1, 100)
        data_queue.put(item)
        print(f"{threading.current_thread().name}Put data in the queue:{item}")


def consumer(data_queue):
    while True:
        try:
            item = data_queue(timeout=3)
            print(f"{threading.current_thread().name}Remove from the queue:{item}")
        except queue.Empty:
            break
        else:
            data_queue.task_done()


def main():
    q = queue.Queue()
    thread = []
    p = threading.Thread(target=produce, args=(q,))
    p.start()

    for i in range(3):
        c = threading.Thread(target=consumer, args=(q,))
        thread.append(c)
    for s in thread:
        s.start()
    for s in thread:
        s.join()
    p.join()


if __name__ == '__main__':
    main()

One put, four in

Twenty-one original articles were published. Approved 0. Visited 164
Private letter follow

Tags: Python

Posted on Mon, 13 Jan 2020 17:29:46 -0800 by tengkie