current position:Home>Python thread 08 uses queues to transform the transfer scenario

Python thread 08 uses queues to transform the transfer scenario

2022-02-01 13:32:51 Lei Xuewei

「 This is my participation 11 The fourth of the yuegengwen challenge 25 God , Check out the activity details :2021 One last more challenge

ceremonial Python Column No 46 piece , Classmate, stop , Don't miss this from 0 The beginning of the article !

In the previous part, we accepted it ( Study ) In line Queue, This time, the academic committee will show you how to use The queue solves the problem of the transfer scenario .

Let's look at the transfer scenario again

The previous two articles show how to read and write repeatedly amount, Cause the result to go wrong .


xuewei_account = dict()
xuewei_account['amount'] = 100

# amount A negative number is the transfer out amount 
def transfer(money):
    for i in range(100000):
        xuewei_account['amount'] = xuewei_account['amount'] + money


 Copy code 

In our previous articles, we used multiple threads to turn the length repeatedly :+1 and -1.

As a rule , The result should still be 100.

This is all the code :

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/11/26 12:02  In the morning 
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat:  Lei Xuewei 
# @XueWeiTag: CodingDemo
# @File : threadsafe_queue1.py
# @Project : hello
import random
import threading
import datetime
import time

xuewei_account = dict()
xuewei_account['amount'] = 100


# amount A negative number is the transfer out amount 
def transfer(money):
    for i in range(100000):
        xuewei_account['amount'] = xuewei_account['amount'] + money


#  establish 20 Transfer money to the account of the school committee repeatedly 
threads = []
for i in range(10):
    t1 = threading.Thread(target=lambda: transfer(-1))
    threads.append(t1)
    t2 = threading.Thread(target=lambda: transfer(1))
    threads.append(t2)

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

print("-" * 16)
print(" Number of active threads :", threading.active_count())
print(" Active threads :", threading.current_thread().name)
print(" The balance of the school committee's account :", xuewei_account)
 Copy code 

Wait for all transfer threads to finish running , We see that the result is wrong :

 Screenshot  2021-11-27  Afternoon 11.21.21.png

How to use queues to solve this problem ?

I said before. , Multithreading repeatedly reads and writes shared data , Is the root of the problem .

Change the code to synchronous mutual exclusion mode , Ensure that one thread updates the shared data at any time , Then the problem is solved .( This also shows , It's using Lock Lock scheme )

How can I use this queue ?

Think about it first 10 second , According to the characteristics of locking and queue learned , Think about how to do this .

good , Here's the answer :

Queue This queue has multiple functions , One is put function , One is get function .

One is responsible for putting data to the end of the team , An element that can be taken from the counterpart .

Just suitable for transfer business , Can we turn each transfer operation into an instruction / event . Like the following :

event(amount=1,acount=xuewei_account)
....
event(amount=-1,acount=xuewei_account)
....
event(amount=1,acount=xuewei_account)
....
event(amount=-1,acount=xuewei_account)
 Copy code 

20 Threads , Every 10 Ten thousand data reads and writes , common 200 Ten thousand Events .

So we can turn this thing into :200 Million transfer events .

because Queue It's thread safe , So we can be concurrent 200 Ten thousand transfers , In addition, it is handed over to a thread for transfer processing .

This ensures that there is only one thread pair at a time xuewei_account Read and write from the school committee account .

reform , Use queues to solve problems

Show me the code :

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/11/26 12:02  In the morning 
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat:  Lei Xuewei 
# @XueWeiTag: CodingDemo
# @File : threadsafe_queue2.py
# @Project : hello
import random
import threading
import datetime
import time
import queue

q = queue.Queue()

xuewei_account = dict()
xuewei_account['amount'] = 100


# amount A negative number is the transfer out amount 
def transfer(money):
    for i in range(100000):
        q.put(money)


def handle_amount():
    while not q.empty():
        amount = q.get()
        xuewei_account['amount'] += amount


def monitor_q():
    counter = 0
    time.sleep(3)
    while counter < 1000 and not q.empty():
        print("q size:", q.qsize())
        time.sleep(3)
        counter+=1


q_thread = threading.Thread(name="Q monitor ", target=monitor_q)
q_thread.start()
#  establish 20 Transfer money to the account of the school committee repeatedly 
threads = []
for i in range(10):
    t1 = threading.Thread(target=lambda: transfer(-1))
    threads.append(t1)
    t2 = threading.Thread(target=lambda: transfer(1))
    threads.append(t2)

for t in threads:
    t.start()

vip_thread = threading.Thread(name=" Deal with the transfer line ", target=handle_amount)
vip_thread.start()



for t in threads:
    t.join()
vip_thread.join()

print("-" * 16)
print(" Number of active threads :", threading.active_count())
print(" Active threads :", threading.current_thread().name)
print(" The balance of the school committee's account :", xuewei_account)
 Copy code 

There are multiple threads running here to execute the transfer ( Send the transfer amount into the queue ).

Then run a vip passageway ( Single thread ) Handle the transfer business of the student committee account .

It also runs a thread that monitors the queue , Print the task status of the queue at regular intervals .

Here are the results , Run several times and the results are correct .

 Screenshot  2021-11-27  Afternoon 11.36.54.png

Run several times, and the final account balance is 100, Successful transformation .

summary

In this article, the student committee shares the thread safe queue Queue Solve the problem of concurrent transfer .

In fact, the code can be optimized again , In order to control the length , There's a lot of code , I hope readers can read and learn , Master the use of queues .

by the way , like Python Friend, , Please pay attention to Python Basic column or Python From getting started to mastering the big column

Continuous learning and continuous development , I'm Lei Xuewei !
Programming is fun , The key is to understand the technology thoroughly .
Welcome to wechat , Like support collection !

copyright notice
author[Lei Xuewei],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/02/202202011332487055.html

Random recommended