python多线程结束线程_python多线程和办公室

python多线程结束线程

I have always been a huge fan of concurrent programming and famous sitcom television series The Office. In this blog I am trying to relate multi-threading in Python with different episodes of The office.

我一直是并发编程和著名的情景喜剧电视剧《办公室》的忠实拥护者。 在这个博客中,我试图将Python中的多线程与The office的不同情节联系起来。

螺纹 (THREADS)

In sequential programming, like a program (process) to print “Hello World!”, the program has a start, a set of sequence of instructions to execute and an end.

在顺序编程中,就像打印“ Hello World!”的程序(过程)一样,该程序有一个开始,一组要执行的指令序列和一个结束。

Image for post

Just like sequential programming, a thread has a start, a set of sequence of instructions to execute and an end. But threads cannot coexist without a process. In other words, threads are a subset of a process. Operating system schedules execution of the threads based on a scheduling algorithm.

就像顺序编程一样,线程有一个开始,一组要执行的指令序列和一个结束。 但是,如果没有进程,线程将无法共存。 换句话说,线程是进程的子集。 操作系统根据调度算法来调度线程的执行。

Image for post

As an analogy one can visualize television series “The Office” as a process and every character in the television series as an individual thread. The office show has a beginning, a set of sequence of instructions (or episodes) and an end, just like each of the characters (threads). Characters play their part and are terminated either when the script demands (operating system)or when the show ends (process).

作为类比,可以将电视连续剧“办公室”形象化为一个过程,并将电视连续剧中的每个角色形象化为一个单独的线索。 就像每个角色(线程)一样,办公室表演有一个开始,一组指令(或情节)和一个结尾。 角色扮演角色,并在脚本要求(操作系统)或放映结束(过程)时终止。

线程的生命周期 (LIFECYCLE OF A THREAD)

Image for post

Broadly speaking thread has 4 states. New, when thread is defined. Runnable is when it has all the resources required to go into execution state.Waiting, when thread is waiting for a resource and Terminated when thread is done with execution.

从广义上讲,线程具有4个状态。 新建(定义线程)。 Runnable是指拥有进入执行状态所需的所有资源的时间。等待时,线程正在等待资源;等待线程完成执行时终止。

实施线程 (IMPLEMENTING THREADS)

Python provides a threading library for multi-threading implementation. Let us consider the code sample below. Following code depicts “Michael Scott’s Dunder Mifflin Scranton Meredith Palmer Memorial Celebrity Rabies Awareness Pro-Am Fun Run Race for the Cure” fun run, to implement threads.

Python提供了用于多线程实现的线程库 。 让我们考虑下面的代码示例。 下面的代码描绘了“ 迈克尔·斯科特的邓德·米夫林·斯克兰顿·梅勒迪斯·帕尔默纪念名人狂犬病意识亲美趣味跑比赛”,以实现线程。

import threading
import timedef get_lamp():
``` When life gives you a race you buy a lamp from yard sale ```
time.sleep(1)def get_beer():
``` Well beer always gets preference over running ```
time.sleep(5)def running():
``` Everyone is running hard. Well almost everyone! ```
name = threading.current_thread().getName()
print(f"{name} started running...")
if name == "Jim" or "Pam":
get_lamp()
if name == "Stanley":
get_beer()
time.sleep(0.5)
print(f"{name} Finished race")if __name__ == '__main__':
characters = ["Toby", "Michael", "Dwight", "Angela",
"Jim", "Pam", "Stanley"]
threads = list() # Defining different threads for each character
for character in characters:
threads.append(threading.Thread(target=running,
name=character)) # This will start the threads
for thread in threads:
thread.start()
print(f'active thread count: {threading.active_count()}') # Waiting for all the threads to finish execution
for thread in threads:
thread.join()
print("Race is finished")

Sample output

样品输出

Toby started running...
Michael started running...
Dwight started running...
Angela started running...
Jim started running...
Pam started running...
Stanley started running...
active thread count: 8
Toby Finished race
Michael Finished race
Pam Finished race
Angela Finished race
Jim Finished race
Dwight Finished race
Stanley Finished race
Race is finished

In main function we have defined all the characters which will be participating in the race.Function running is executed by multiple threads. In code snippet, thread.start() will start execution of the the thread. However, while running Jim and Pam found a yard sale and decided to get a lamp. This is represented by get_lamp function. While Stanley being Stanley, preferred a beer over a run. Thread Stanley calls get_beer function. To wait for all the threads to finish execution, thread.join is used. When all the threads return to main function after execution, race is finished.

在主要功能中,我们定义了将要参加比赛的所有角色。功能运行由多个线程执行。 在代码段中,thread.start()将开始执行线程。 然而,吉姆和帕姆(Jam and Pam)在奔跑时发现了一家院子里的买卖,决定买一盏灯。 这由get_lamp函数表示。 斯坦利(Stanley)担任斯坦利(Stanley)时,更喜欢啤酒。 线程Stanley调用get_beer函数。 为了等待所有线程完成执行,使用thread.join。 当所有线程执行完后返回主函数时,竞赛结束。

互斥 (MUTUAL EXCLUSION)

Threads does make program faster but causes other issues when multiple threads read and write on shared data. Such a part of code which has a shared resource is called critical section. Python threading module provides Lock to protect the critical section.

线程的确使程序运行更快,但是当多个线程在共享数据上读写时,会引起其他问题。 这样具有共享资源的代码部分称为关键部分 。 Python线程模块提供了Lock来保护关键部分。

import threading
import timecount_lock = threading.Lock()
MAX_THREAD = 10def thanking_you():
name = threading.current_thread().getName()
count_lock.acquire()
print(f'{name} would like to thank you!')
count_lock.release()if __name__ == '__main__':
for thread_count in range(MAX_THREAD):
threading.Thread(target=thanking_you, name='Dwight').start()
threading.Thread(target=thanking_you, name='Andy').start()
print("Enough of thanking already!")

Sample output

样品输出

Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Enough of thanking already!

In the example of above, 2 threads Dwight and Andy, who keep thanking each other till MAX_THREAD count in reached. Print statement to thank is the critical section. Thread Dwight will first execute function thanking_you and acquire thank_lock, which prohibits thread Andy to execute critical section. Thread Andy will wait for thread Dwight to release the lock before executing critical section.

在上面的示例中,两个线程Dwight和Andy一直互相感谢,直到达到MAX_THREAD计数为止。 打印声明要感谢的是关键部分。 线程Dwight将首先执行函数thanking_you并获取thank_lock,这将阻止线程Andy执行关键部分。 线程Andy将在执行关键部分之前等待线程Dwight释放锁定。

Let’s modify the thanking_you function a little.

让我们稍微修改thanking_you函数。

def thanking_you():
name = threading.current_thread().getName()
thank_lock.acquire()
for i in range(5):
thank_lock.acquire()
print(f'{name} would like to thank you!')
thank_lock.release()

In the code snippet above, each thread would like to thank 5 times in a row. And for every print statement thread will try to acquire the lock. This leads to a problem.

在上面的代码片段中,每个线程连续要感谢5次。 并且对于每个打印语句,线程将尝试获取锁。 这导致问题。

Let’s say thread Dwight is the first thread executing function thanking_you. It can only acquire lock thank_lock when it’s in released state. In first iteration of the for loop when thread Dwight is executing critical function, it acquires the lock. In second iteration it tries to acquire the lock again which thread Dwight already has. Since lock is not in released state, thread Dwight will wait on itself forever to acquire the lock. To resolve such an issue we can use Rlock from the threading library.

假设线程Dwight是第一个线程执行函数Thanking_you。 它只有在释放状态时才能获取锁thank_lock。 在线程Dwight执行关键功能时,在for循环的第一次迭代中,它获取锁定。 在第二次迭代中,它尝试再次获取Dwight已经拥有的线程的锁。 由于锁未处于释放状态,因此线程Dwight将永远等待自身以获取锁。 要解决此问题,我们可以使用线程库中的Rlock

import threading
import timethank_lock = threading.RLock()
MAX_THREAD = 10def thanking_you():
name = threading.current_thread().getName()
thank_lock.acquire()
for i in range(5):
thank_lock.acquire()
print(f'{name} would like to thank you!')
thank_lock.release()if __name__ == '__main__':
threads = list()
threads.append(threading.Thread(target=thanking_you,
name='Dwight'))
threads.append(threading.Thread(target=thanking_you,
name='Andy'))# starting threads
for thread in threads:
thread.start()# waiting for threads to finish
for thread in threads:
thread.join()print("Enough of thanking already!")

Sample output

样品输出

Dwight would like to thank you!
Dwight would like to thank you!
Dwight would like to thank you!
Dwight would like to thank you!
Dwight would like to thank you!
Andy would like to thank you!
Andy would like to thank you!
Andy would like to thank you!
Andy would like to thank you!
Andy would like to thank you!
Enough of thanking already!

A reentrant lock (Rlock) can be used to acquire the lock by the thread that already has the lock acquired.

可重入锁(Rlock)可用于通过已获取锁的线程来获取锁。

使用螺纹将参数传递给功能 (PASSING ARGUMENTS TO A FUNCTION USING THREADS)

Till now we have been calling a function which doesn’t accept any argument in function call. I am going to use classic, inspirational, thriller, critically acclaimed, bold, highly original and my all time favorite movie, “Threat level midnight!” to demonstrate this.

到现在为止,我们一直在调用一个在函数调用中不接受任何参数的函数。 我将使用经典,鼓舞人心的惊悚片,广受好评的,大胆的,高度原创的影片,以及我一直以来最喜欢的电影“威胁级别的午夜!” 证明这一点。

import threading
import timecharacters_survival_dict = dict()def thread_level_midnight(character=None):
# list of characters killed in the movie
killed_characters_list = ["Toby", "Oscar", "Creed"]
if character in killed_characters_list:
characters_survival_dict[character] = "Killed"
else:
characters_survival_dict[character] = "Alive"if __name__ == '__main__':
characters = ["Toby", "Michael", "Dwight", "Angela",
"Jim", "Pam", "Stanley", "Oscar", "Creed"]
threads = list()# Defining different threads for each character
for character in characters:
threads.append(threading.Thread(
target=thread_level_midnight,
kwargs=dict(character=character),
name=character)
)# This will start the threads
for thread in threads:
thread.start()
print(f'active thread count: {threading.active_count()}')# Waiting for all the threads to finish execution
for thread in threads:
thread.join()print("Michael Scarn hates:")
for character in characters_survival_dict:
if characters_survival_dict.get(character) == "Killed":
print(character)
print("Threat level what...")
print("midnight!")

Sample output

样品输出

Michael Scarn hates:
Toby
Oscar
Creed
Threat level what...
midnight!

In the code above, function thread_level_midnight accepts character as an argument. When defining a thread, kwargs can be used to pass the argument to function thread_level_midnight.

在上面的代码中,函数thread_level_midnight接受character作为参数。 定义线程时,可以使用kwargs将参数传递给函数thread_level_midnight。

Let’s enhance the function thread_level_midnight to return a value.

让我们增强功能thread_level_midnight以返回值。

import threading
import time
import queuecharacters_survival_queue = queue.Queue()def thread_level_midnight(character=None):
# list of characters killed in the movie
killed_characters_list = ["Toby", "Oscar", "Creed"]
if character in killed_characters_list:
return characterif __name__ == '__main__':
characters = ["Toby", "Michael", "Dwight", "Angela",
"Jim", "Pam", "Stanley", "Oscar", "Creed"]
threads = list()# Defining different threads for each character
for character in characters:
threads.append(
threading.Thread(target=lambda q, arg1: \
q.put(thread_level_midnight(arg1)),
args=(characters_survival_queue,
character))
)# This will start the threads
for thread in threads:
thread.start()
print(f'active thread count: {threading.active_count()}')# Waiting for all the threads to finish execution
for thread in threads:
thread.join()print("Michael Scarn hates:")
while not characters_survival_queue.empty():
result = characters_survival_queue.get()
if result: print (result)
print("Threat level what...")
print("midnight!")

Sample output

样品输出

Michael Scarn hates:
Toby
Oscar
Creed
Threat level what...
midnight!

In the example code above we have used queue to store return values from the function thread_level_midnight.

在上面的示例代码中,我们使用队列来存储来自thread_level_midnight函数的返回值。

This was the part one of the blog on python multi-threading. In next part we will see issues caused by locking if not implemented properly.

这是有关python多线程的博客的一部分。 在下一部分中,我们将看到由锁定引起的问题(如果未正确实施)。

翻译自: https://medium.com/swlh/python-multi-threading-and-the-office-4f44d579e697

python多线程结束线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值