python线程回收_python中线程

线程线程的实质:进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。线程的特性:同一个进程内的多个线程共享该进程内的地址资源,但也任然有自己独立的存储空间创建线程的开销要远小于创建进程的开销(创建一个进程,就是创建一个车间,涉及到申请空间,而且在该空间内建至少一条流水线,但创建线程,就只是在一个车间内造一条流水线,无需申请空间,所以创建开销小)注意:...
摘要由CSDN通过智能技术生成

线程

线程的实质:进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。

线程的特性:

同一个进程内的多个线程共享该进程内的地址资源,但也任然有自己独立的存储空间

创建线程的开销要远小于创建进程的开销(创建一个进程,就是创建一个车间,涉及到申请空间,而且在该空间内建至少一条流水线,但创建线程,就只是在一个车间内造一条流水线,无需申请空间,所以创建开销小)

注意:

加入你的电脑是四核的,我开四个进程的话,每一个进程占用一个cpu来运行,如果开4个线程的话 这四个线程都隶属于一个进程里面,所有4个线程只是占用一个cpu运行(伪并发,GIL锁)

因为解释性语言很难知道当前这一句执行完了下一句是什么,解释器的锅,不是python语言的锅

线程和进程的使用场景:

如果两个任务,需要共享内存,又想实现异步,使用多线程

如果两个任务,需要数据隔离,使用多进程

全局解释器锁(GIL锁)解释为什么Cpython没法使用多核优势

GIL本质就是一把互斥锁,既然是互斥锁,所有互斥锁的本质都一样,都是将并发运行变成串行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证数据安全。

首先确定一点:运行python文件实际上是运行python解释器的进程,每次执行python程序,都会产生一个独立的进程。例如python test.py,python aaa.py,python bbb.py会产生3个不同的python进程

解释器的代码是所有线程共享的,所以垃圾回收线程也可能访问到解释器的代码而去执行,这就导致了一个问题:对于同一个数据100,可能线程1执行x=100的同时,而垃圾回收执行的是回收100的操作,解决这种问题没有什么高明的方法,就是加锁处理,如下图的GIL,保证python解释器同一时间只能执行一个任务的代码

注:上图表示多个线程同时执行python代码,然后和垃圾回收线程一起访问解释器代码

GIL与Lock

机智的同学可能会问到这个问题:Python已经有一个GIL来保证同一时间只能有一个线程来执行了,为什么这里还需要lock?

首先,我们需要达成共识:锁的目的是为了保护共享的数据,同一时间只能有一个线程来修改共享的数据

然后,我们可以得出结论:保护不同的数据就应该加不同的锁。

最后,问题就很明朗了,GIL 与Lock是两把锁,保护的数据不一样,前者是解释器级别的(当然保护的就是解释器级别的数据,比如垃圾回收的数据),后者是保护用户自己开发的应用程序的数据,很明显GIL不负责这件事,只能用户自定义加锁处理,即Lock,如下图

有了GIL的存在,同一时刻同一进程中只有一个线程被执行

听到这里,有的同学立马质问:进程可以利用多核,但是开销大,而python的多线程开销小,但却无法利用多核优势,也就是说python没用了,php才是最牛逼的语言?

这里就回到了最开始的地方:线程和进程的使用场景:

如果两个任务,需要共享内存,又想实现异步,使用多线程

如果两个任务,需要数据隔离,使用多进程

python线程模块的选择

Python提供了几个用于多线程编程的模块,包括thread、threading和Queue等。thread和threading模块允许程序员创建和管理线程。thread模块提供了基本的线程和锁的支持,threading提供了更高级别、功能更强的线程管理的功能。Queue模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。

避免使用thread模块,因为更高级别的threading模块更为先进,对线程的支持更为完善,而且使用thread模块里的属性有可能会与threading出现冲突;其次低级别的thread模块的同步原语很少(实际上只有一个),而threading模块则有很多;再者,thread模块中当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作,至少threading模块能确保重要的子线程退出后进程才退出。

thread模块不支持守护线程,当主线程退出时,所有的子线程不论它们是否还在工作,都会被强行退出。而threading模块支持守护线程,守护线程一般是一个等待客户请求的服务器,如果没有客户提出请求它就在那等着,如果设定一个线程为守护线程,就表示这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。

threading模块

multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍

线程的创建Threading.Thread类

创建线程的方式1

from threading import Thread

import time

def sayhi(name):

time.sleep(2)

print('%s say hello' %name)

if __name__ == '__main__':

t=Thread(target=sayhi,args=('egon',))

t.start()

print('主线程')

创建线程的方式2

from threading import Thread

import time

class Sayhi(Thread):

def __init__(self,name):

super().__init__()

self.name=name

def run(self):

time.sleep(2)

print('%s say hello' % self.name)

if __name__ == '__main__':

t = Sayhi('egon')

t.start()

print('主线程')

注意:在主进程下开启多个线程,每个线程都跟主进程的pid一样,而开多个进程,每个进程都有不同的pid

t.start()和t.run(),start会自动调用run,但是调用start会自动执行run,但是不一定会立即执行,是等待调度,何时真正的被调度取决于cpu,而调用t.run则是直接执行线程对象的run方法

线程相关的基本方法和使用

Thread实例对象的方法

isAlive(): 返回线程是否活动的。

getName(): 返回线程名。

setName(): 设置线程名。

threading模块提供的一些方法:

threading.currentThread(): 返回当前的线程变量。

threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

使用实例

from threading import Thread

import threading

from multiprocessing import Process

import os

def work():

import time

time.sleep(3)

print(threading.current_thread().getName())

if __name__ == '__main__':

#在主进程下开启线程

t=Thread(target=work)

t.start()

print(threading.current_thread().getName())

print(threading.current_thread()) #主线程

print(threading.enumerate()) #连同主线程在内有两个运行的线程

print(threading.active_count())

print('主线程/主进程')

'''

打印结果:

MainThread

[<_mainthread started>, ]

主线程/主进程

<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很抱歉,我之前回答的还是这个问题。以下是一个稍微复杂一点的 Python线程实例,可以用来计算一个矩阵的乘积: ```python import threading import numpy as np # 定义矩阵的大小 MATRIX_SIZE = 1000 # 初始化两个随机矩阵 matrix_a = np.random.rand(MATRIX_SIZE, MATRIX_SIZE) matrix_b = np.random.rand(MATRIX_SIZE, MATRIX_SIZE) # 初始化结果矩阵 result_matrix = np.zeros((MATRIX_SIZE, MATRIX_SIZE)) # 定义一个函数,用来计算矩阵的乘积 def multiply(start, end): for i in range(start, end): for j in range(MATRIX_SIZE): for k in range(MATRIX_SIZE): result_matrix[i][j] += matrix_a[i][k] * matrix_b[k][j] # 定义线程数量 NUM_THREADS = 4 # 计算每个线程需要计算的行数 rows_per_thread = MATRIX_SIZE // NUM_THREADS # 创建线程列表 threads = [] # 启动线程 for i in range(NUM_THREADS): start = i * rows_per_thread end = (i + 1) * rows_per_thread t = threading.Thread(target=multiply, args=(start, end)) threads.append(t) t.start() # 等待所有线程结束 for t in threads: t.join() # 检查结果是否正确 expected_result = np.dot(matrix_a, matrix_b) assert np.array_equal(result_matrix, expected_result) # 输出 Done 表示程序执行完毕 print("Done") ``` 这个例子首先初始化两个随机矩阵,然后定义一个函数 multiply,用来计算这两个矩阵的乘积。然后,它将矩阵分成若干个部分,每个部分分配给一个线程来计算。最后,它等待所有线程结束,检查结果是否正确,并输出 Done 表示程序执行完毕。 希望这个例子能够帮助您更好地理解 Python线程的使用方法。 ### 回答2: Python线程实例是指在Python编程语言使用多线程进行并发编程的实例。在Python,可以使用内置的threading模块来创建和管理多线程。 通过创建多线程,可以在程序同时执行多个任务。这对于需要同时处理多个任务的情况非常有用。例如,在下载大文件时,可以使用多线程同时下载多个文件,加快下载速度。此外,多线程还可以用于处理网络请求、图像处理、数据处理等耗时操作,提高程序的运行效率。 使用Python线程的主要步骤如下: 1. 导入threading模块。 ``` import threading ``` 2. 创建一个线程对象,可以通过继承threading.Thread类或使用threading.Thread()函数创建。 ``` class MyThread(threading.Thread): def __init__(self, name): super().__init__() self.name = name def run(self): # 线程执行的代码 print("Hello, " + self.name) thread1 = MyThread("Thread 1") thread2 = threading.Thread(target=func, args=("Thread 2",)) ``` 3. 启动线程。 ``` thread1.start() thread2.start() ``` 4. 等待线程结束。 ``` thread1.join() thread2.join() ``` 以上代码演示了两种创建多线程的方法:1)继承threading.Thread类,重写run方法;2)使用函数作为线程的执行内容。线程的启动调用start()方法,等待线程结束使用join()方法。 需要注意的是,Python线程的并发程度受到全局解释器锁(GIL)的限制,因此对于计算密集型的任务,多线程并不能发挥出多核的优势。如果需要发挥多核性能,可以考虑使用多进程编程。 总之,Python线程实例能够提高程序的并发处理能力,适用于需要同时处理多个任务的场景。通过合理设计线程的数量和任务分配,可以提高程序的性能和效率。 ### 回答3: Python线程实例是指通过使用多线程的技术来提高Python程序的运行效率和性能。在Python,我们可以使用threading模块来实现多线程。 多线程技术可以同时执行多个任务,提高程序的运行速度。在Python,我们可以通过创建Thread对象并调用start()方法来启动一个线程。下面是一个简单的例子: import threading def print_numbers(): for i in range(1, 11): print(i) def print_letters(): for letter in ['A', 'B', 'C', 'D', 'E']: print(letter) # 创建两个线程 t1 = threading.Thread(target=print_numbers) t2 = threading.Thread(target=print_letters) # 启动两个线程 t1.start() t2.start() # 等待两个线程结束 t1.join() t2.join() # 主线程继续执行 print("主线程结束") 以上代码,我们创建了两个线程,分别执行print_numbers()和print_letters()函数。通过调用start()方法启动线程,并通过join()方法等待两个线程执行完毕。最后,主线程继续执行并打印出一段文字。 需要注意的是,多线程并不一定能提高程序的运行速度,因为在Python,全局解释器锁(Global Interpreter Lock,GIL)会限制同一时间只能有一个线程执行Python字节码。因此,在CPU密集型任务,多线程并不能真正实现并行计算。但是,在IO密集型任务,多线程能够提高程序的运行效率。 总结起来,Python的多线程实例可以通过使用threading模块来实现。多线程能够提高IO密集型任务的运行效率,但在CPU密集型任务并不能真正实现并行计算。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值