多线程创建
import time
import threading
import requests
t=threading.Thread(target=函数名,args=(函数参数,))最后要加个逗号
t.start()
t.join()等待
python设置守护线程
守护线程 (True) 必须放在start自之前
设置守护线程,主线程执行完毕之后,子线程自动关闭
非守护线程,主线程会等子线程
t=threading.Thread(target=task,args=(12,))
#守护线程 (True) 必须放在start自之前
#设置守护线程,主线程执行完毕之后,子线程自动关闭
#非守护线程,主线程会等子线程
t.setDaemon(True) #就不会打印任务了
t.start()
print("over")
python线程也可以,自己设置名字setName,获取名称getName,,也要在start之前设置名字
也可以设置自己的线程类去继承thread.Thread类,里面执行的方法必须叫run,接收的参数就是_args
Python通过两个标准库thread和threading提供对线程的支持。thread提供了低级别的、原始的线程以及一个简单的锁。
threading 模块提供的其他方法:
除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
多线程肯定就要涉及同步问题了,python里面thread对象有lock,和rlock锁直接用
使用Thread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有acquire方法和release方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到acquire和release方法之间。
1.1 Lock:
Lock锁是Python的原始锁,在锁定时不属于任何一个线程。在调用了 lock.acquire() 方法后,进入锁定状态,lock.release()方法可以解锁。底层是通过一个函数来实现的,会根据不同的操作系统选择一个最有效的版本实例
1.2 RLock:
RLock被称为重入锁,RLock锁是一个可以被同一个线程多次 acquire 的锁,但是最后必须由获取它的线程来释放它,不论同一个线程调用了多少次的acquire,最后它都必须调用相同次数的 release 才能完全释放锁,这个时候其他的线程才能获取这个锁。acquire()/release() 对可以嵌套,重入锁必须由获取它的线程释放。一旦线程获得了重入锁,同一个线程再次获取它将不阻塞。
def print_time(threadname,waittimes,xunhuan):
while xunhuan:
time.sleep(waittimes)
print("%s:%s"%(threadname,time.ctime(time.time())))
xunhuan-=1
class mythread(threading.Thread):
def __init__(self,threadid,name,waitime):
threading.Thread.__init__(self)
self.threadid=threadid
self.name=name
self.waitime=waitime
def run(self):
print("执行线程",self.name)
# 获得锁,成功获得锁定后返回True
# 可选的timeout参数不填时将一直阻塞直到获得锁定
# 否则超时后将返回False
threadlock.acquire()
print_time(self.name,self.waitime,2)
#释放锁
threadlock.release()
threadlock=threading.Lock()
threads=[]
#创建线程
t1=mythread(1,"thread-1",1)
t2=mythread(2,"thread-2",2)
t1.start()
t2.start()
threads.append(t1)
threads.append(t2)
for t in threads:
t.join()
print("over")
多进程创建
#windows是spawn模式创建的进程,多进程写 要放在__name__=__main__这个里面
#linux 是基于fork做的,所以创建进程放在哪都行
import multiprocessing
t=multiprocessing.Process(target=函数名,args=(函数参数))
t.start()
python进程独有进程锁
GIL锁
python3自带线程池
需要导入concurrent模块
concurrent.futures主要实现了进程池和线程池,适合做派生一堆任务,异步执行完成后,再收集这些任务,
from concurrent.futures import ThreadPoolExecutor
import threading
def task(arg):
print("任务开始",arg)
sleep(5)
#创建线程池,最多维护10个线程
pool=ThreadPoolExecutor(10)
arg_list=["wwww.xxx-{}.com".format(i) for i in range(100)]
for xx in arg_list:
#在线程池中提交一个任务,线程池如果有空闲线程,则分配一个线程去执行,
#执行完毕后再讲线程还给线程池
pool.submit(task,xx)
print("执行中")
pool.shutdown(True) #等着线程池里任务全部执行完毕了 ,才往下走
print("继续往下")
可以看看
python并发编程入门:(四)concurrent.futures - 知乎 (zhihu.com)