python 进程与线程

线程
1 .简述进程和线程的区别以及应用场景
#线程,是计算机中可以被cpu调度的最小单元(真正在工作)
#进程,是计算机资源分配的最小单元
	#计算密集型,适用多进程开发
    #IO密集型,适用多线程开发
2.GIL锁

全局解释器锁,控制一个进程中同一时刻只有一个线程可以被cpu调度

3 线程的常用方法
3-1 t.start()

当前线程准备就绪 (等待cpu调度,具体时间是由cpu来决定)

import threading

def funs(name):
    print(name)
 for li in range(10):
    t1=threading.Thred(target=funs,args=(li,))
    t1.start()
3-2 t.join()

等待当前线程的任务执行完毕后再向下继续执行。

import threading

t=threading.Thred(target=fun)
t.start() #子线程被调用
t.join() #主线程等待
3-3 t.setDaemon(布尔值)

守护线程(必须放在start之前)

import threading
t=threading.Thread(target=fun,args=('tian',li))
# True 设置守护线程,主线程执行完毕后,子线程也自动关闭
 t.setDaemon(True)  
#  设置为非守护线程,主线程等待子线程,子线程执行完毕后,主线程才结束(默认)
t.setDaemon(False)
 t.start()
3-4 线程名称的设置和获取
import threading
def task(arg):
    #获取当前执行此代码的线程
    name = threading.current_thread().getName()
    print(name)
    
for i in range(10):
    t=threading.Thread(target=task,args=(11))
    #设置线程名
    t.setName('hello{}'.format(i))
    t.start()
    
3-5 自定义线程类

直接将线程需要做的事写到run方法中。

# 不使用初始化的方式传参
import threading
class MyThread(threading.Thread):
    def run(self, thread_id, name):
        self.thread_id = thread_id
        self.name = name
        print(f"Starting {self.name}")
        # 线程具体逻辑
        print(f"Exiting {self.name}")

if __name__ == '__main__':
    # 创建新线程并传递参数
    thread1 = MyThread(target=MyThread.run, args=(1, "Thread-1"))
    thread2 = MyThread(target=MyThread.run, args=(2, "Thread-2"))
    # 开启新线程
    thread1.start()
    thread2.start()
    # 等待所有线程完成
    thread1.join()
    thread2.join()
    print("Exiting main thread")


    
    #使用初始化方式传参
import threading
class MyThread(threading.Thread):
    def __init__(self,age,name):
        self.age=age
        self.name=name
    def run(self):
        print('执行此线程',self.age,self.name)
t=mythread(18,'tian')
t.start()
4 线程安全
4-1 加锁

import threading
#创建锁
lock_object = threading.RLock()
loop= 100000
number =0
def add(count):
    #加锁
    lock_object.acquire()
	global number
    for i in range(count):
        number+=1
     #解锁
     lock_object.release()
        
 def sub(count):
	    #加锁
    lock_object.acquire()
	global number
    for i in range(count):
        number-=1
     #解锁
     lock_object.release()
        
        
        
# add()和sub() 使用了同一把锁,这样才能让线程安全,  
5 线程锁

在程序中如果想要自己手动加锁,一般有两种:Lock和RLock

在使用线程锁时,应该保证获取锁和释放锁的顺序正确,否则可能会出现死锁的情况。因此,建议使用 with lock: 的上下文管理器来自动获取和释放线程锁

5-1 Lock 同步锁
import threading

lock_object=threading.Lock()
def task():
    print()
    lock_object.acquire() #上锁
    pass
	lock_object.release() #解锁  线程出去,其他线程就可以进行并执行了
    
5-2 RLock 递归锁
import threading
lock=threading.RLock()
def func():
    with lock:
        pass
def run():
    print()
    func()
    
def process():
    with lock:   
        print()
        lock()  #这里已经加了两个锁,使用Lock()会锁死,使用RLock()不会锁死
        
t1=threading.Thread(target=run)
t2=threading.Thread(target=process)
t1.start()
t2.start()
t1.join()
t2.join()
6 线程池

1

from concurrent.futures import ThreadPoolExecutor
#创建了100个线程
pool= ThreadPoolExecutor(100)
def task(url):
    pass
url_list=['www.xxx-{}.com'.format(i) for i in range(300)]
for url in url_list:
    pool.submit(task,url)

2 等待执行 shutdown(True) 与join()类似

from concurrent.futures import ThreadPoolExecutor
pool= ThreadPoolExecutor(100)
def task(url):
    pass
url_list=['www.xxx-{}.com'.format(i) for i in range(300)]
for url in url_list:
    pool.submit(task,url)
    
print("执行中")
pool.shutdown(True)  #等待线程池中的任务执行完毕后,在继续执行
print("继续往下走")

分工模式

import concurrent.futures as poo
import random
pool=poo.ThreadPoolExecutor(10)

def get_request(url):
    pass
    return random.randint(1,100)

def down(res):
    # res=response.result()
    res=res.result()
    print(res)

for li in range(10):
    wood=pool.submit(get_request,li)
    wood.add_done_callback(down)

分工模式 (闭包使用)

import concurrent.futures as poo
import random
pool=poo.ThreadPoolExecutor(10)

def get_request(url):
    pass
    return random.randint(1,100)

def fun(li):
    def down(res):
        # res=response.result()
        res=res.result()
        print(f"{li}{res}")
    return down

# 说明  在分工模式中,down(res)只能接受一个形参,如果想接受多个形参,要使用到闭包,在闭包中,可以传入多个参数
for li in range(10):
    wood=pool.submit(get_request,li)
    wood.add_done_callback(fun(li))

4 线程池加锁

需要注意的是,在使用线程池时,推荐使用 with concurrent.futures.ThreadPoolExecutor() 上下文管理器,以确保线程池中的工作线程能够正确地启动和关闭。同时,在线程池中使用线程锁时,需要保证获取锁和释放锁的顺序正确,否则可能会出现死锁的情况。

import concurrent.futures
import threading

count = 0     # 共享资源
lock = threading.Lock()    # 创建线程锁对象

def worker(id):
    global count, lock
    for i in range(100000):
        with lock:
            count += 1
    print(f"Worker {id} finished")

if __name__ == '__main__':
    # 创建线程池并提交任务
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        executor.submit(worker, 1)
        executor.submit(worker, 2)

    print(f"Final count: {count}")
# Linux系统fork,win:spawn mac:fork和spawn  (python默认 spawn)
#所以 在win下,运行进程的程序不在“if __name__ == '__main__': ”这里面,这会报错, 解决方法
multiprocessing.set_start_method('fork')


Executor(max_workers=2) as executor:
        executor.submit(worker, 1)
        executor.submit(worker, 2)

    print(f"Final count: {count}")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值