python并发编程(多线程)

本文介绍了Python中的多线程编程,包括线程理论、开启线程的两种方式、线程对象的属性和方法、守护线程、线程互斥锁以及递归锁的使用,最后讨论了线程池的概念。

目录:

  1. 线程理论
  2. 开启线程的两种方式
  3. 线程对象的属性和方法
  4. 守护线程
  5. 线程互斥锁
  6. 互斥锁与递归锁
  7. 线程池

线程理论

1.什么是线程?

进程:资源单位(起一个进程仅仅只是在内存中开辟一块空间)
线程:执行单位(真正被cpu执行的其实是线程,线程其实指的就是代码的执行过程,执行代码中需要的数据找进程这个资源单位要!)
也就意味着进程中真正在执行功能的其实是它里面的线程,即每个进程内部都必须起码有一个线程

2.为什么要有线程?

  • 同一个进程下的多个线程共享该进程内的资源
  • 创建线程的开销要远远小于进程

开启线程的两种方式

from threading import Thread
import time


# 第一种方式
def task(name):
    print('%s is running' % name)
    time.sleep(3)
    print('%s is end' % name)


t = Thread(target=task, args=('jason',))
t.start()  # 创建线程  这句话一运行完 线程几乎就已经创建完毕了
print('主')


# 第二种方式
class MyThread(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        print('%s is running' % self.name)
        time.sleep(3)
        print('%s is end' % self.name)


t = MyThread('jason')
t.start()
print('主')

回到目录

线程对象的属性和方法

# 1.验证线程之间数据共享
from threading import Thread
import time
n=100
def task():
    global n
    n=0
if __name__ == '__main__':
    t=Thread(target=task)
    t.start()
    t.join()
    print('主',n)
    
# 2.线程之间os.getpid() >>> 相等
from threading import Thread
import time,os
def task():
    print('%s is running' %os.getpid())
if __name__ == '__main__':
    t=Thread(target=task)
    t.start()
    print('主',os.getpid())

# 3.active_count当前活跃的线程个数,当前线程
from threading import Thread,active_count,current_thread
import time,os
def task():
    print('%s is running' %current_thread().name)
    time.sleep(2)
if __name__ == '__main__':
    t=Thread(target=task,)
    t.start()
    # t.join()
    # print('主',active_count())
    print('主',current_thread().name)

守护线程

# 进程自带的那个线程运行结束,守护线程立即结束
"""
主线程会等待所有非守护线程的结束,原因在于主线程结束意味着当前进程结束,空间资源均被回收
很明显子线程可能还在运行,明显不合理!
"""
from threading import Thread
import time
def task(name):
    print('%s is running' %name)
    time.sleep(2)
    print('%s is done' %name)
if __name__ == '__main__':
    t=Thread(target=task,args=('线程1',))
    t.daemon=True
    t.start()
    print('主')
# 稍微有点迷糊人的例子
from threading import Thread
from multiprocessing import Process
import time
def foo():
    print(123)
    time.sleep(1)
    print("end123")
def bar():
    print(456)
    time.sleep(3)
    print("end456")
if __name__ == '__main__':
  	t1=Thread(target=foo)
    t2=Thread(target=bar)
    t1.daemon=True
    t1.start()
    t2.start()
    print("main-------")
"""
123
456
main-------
end123
end456
"""

回到目录

线程互斥锁

from threading import Thread,Lock
import time

mutex=Lock()  # 创建线程不需要从头到位再执行代码拷贝数据
n=100
def task():
    global n
    mutex.acquire()
    temp=n
    time.sleep(0.1)
    n=temp-1
    mutex.release()

if __name__ == '__main__':
    t_l=[]
    for i in range(100):
        t=Thread(target=task)
        t_l.append(t)
        t.start()

    for t in t_l:
        t.join()
    print(n)

互斥锁与递归锁

from threading import Thread,Lock,RLock
import time

# mutexA=Lock()
# mutexB=Lock()
mutexB=mutexA=RLock()


class Mythead(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print('%s 抢到A锁' %self.name)
        mutexB.acquire()
        print('%s 抢到B锁' %self.name)
        mutexB.release()
        mutexA.release()

    def f2(self):
        mutexB.acquire()
        print('%s 抢到了B锁' %self.name)
        time.sleep(2)
        mutexA.acquire()
        print('%s 抢到了A锁' %self.name)
        mutexA.release()
        mutexB.release()

if __name__ == '__main__':
    for i in range(100):
        t=Mythead()
        t.start()

回到目录

线程池

from concurrent.futures import ThreadPoolExecutor
import time
import os
# 实例化池对象
# 不知道参数的情况,默认是当前计算机cpu个数乘以5,也可以指定线程个数
pool = ThreadPoolExecutor(20)  # 创建了一个线程池子,池子里面有20个线程
# pool = ProcessPoolExecutor(5)  # 创建了一个池子
def task(n):
    print(n,os.getpid())
    time.sleep(2)
    return n**2
def call_back(n):
    print('我拿到了结果:%s'%n.result())
"""
提交任务的方式
    同步:提交任务之后,原地等待任务的返回结果,再继续执行下一步代码
    异步:提交任务之后,不等待任务的返回结果(通过回调函数拿到返回结果并处理),直接执行下一步操作
"""
# 回调函数:异步提交之后一旦任务有返回结果,自动交给另外一个去执行
if __name__ == '__main__':
    # pool.submit(task,1)
    t_list = []
    for i in range(20):
        future = pool.submit(task,i).add_done_callback(call_back)  # 异步提交任务
        t_list.append(future)

    # pool.shutdown()  # 关闭池子并且等待池子中所有的任务运行完毕
    # for p in t_list:
    #     print('>>>:',p.result())
    print('主')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值