python---多线程

全局变量是数据共享

各个线程是异步的

高计算用多进程--全局解释器锁GIL--同一时刻只能有一个线程被CPU执行

第一种方法函数法:

import threading  #线程库
import time
def func(n):     #线程函数
    time.sleep(1)
    print('线程:',n)
for i in range(10):
    t=threading.Thread(target=func,args=(i,))  #创建线程对象;func线程中要执行的函数;args=(1,)传递的参数(元组)
    t.start()    #启动线程
print('主线程')

线程函数执行完毕,线程自动释放

第二种方法类继承法:

import threading
import time
class mythread(threading.Thread):#继承threading.Thread
    def __init__(self,n):
        super().__init__()
        self.n=n
    def run(self):     #线程要执行的函数;n是参数
        time.sleep(1)
        print('子线程%s'%self.n)
for i in range(10):
    t=mythread(i)   #创建线程对象
    t.start()

t.join()  #等待t线程结束再继续执行

可以设置一个时间参数n:单位秒

当t是守护线程时,含义是主线程对于子线程等待n秒的时间将会杀死该子线程。简单的来说,就是给每个子线程一个n秒的时间,让他去执行,时间一到,不管任务有没有完成,直接杀死

t不是守护线程时,主线程将会等待n秒时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束

t.setDaemon(True)    把线程B设置为守护线程. 要是主线程A执行结束了,就不管子线程B是否完成,一并和主线程A退出, 必须在start() 方法调用之前设置

如果设置为false非守护线程,主线程退出时会等待子线程完毕才退出

线程的一些方法:

import threading
import time
def func(n):
    time.sleep(1)
    print('子线程',threading.current_thread())    #返回当前线程,是对象.<_MainThread(MainThread, started 17824)>;<Thread(Thread-1, started 17880)>
    print('子线程', threading.current_thread().name) #返回线程名称。MainThread;Thread-1
    print('子线程', threading.current_thread().getName())   #返回线程名称。MainThread;Thread-1
for i in range(2):
    t=threading.Thread(target=func,args=(i,))  #创建线程对象;func线程中要执行的函数;args=(1,)传递的参数(元组)
    t.start()
print('主线程',threading.current_thread())
print('主线程',threading.current_thread().name)
print('主线程',threading.current_thread().getName())
print(t.isAlive())   #返回线程t是否还在执行
print(t.is_alive())   #返回线程t是否还在执行
print(threading.active_count())  #返回线程总数=主线程+子线程
print(threading.enumerate())   #返回所有线程对象。列表

线程递归锁Rlock:

互斥锁Lock只有一把钥匙

递归锁Rlock可以有n把钥匙

简言之:Lock属于全局,Rlock属于线程

import threading
import time
rlock1=rlock2=threading.RLock()   #创建钥匙串,钥匙串中有两把锁
def eat1(name):
    rlock1.acquire()     #上第一把锁;已经获得钥匙串,别的线程不能获取钥匙串了
    print('%s拿了叉子'%name)
    time.sleep(1)
    rlock2.acquire()   #上第二把锁,同一线程可以多次上锁
    print('%s拿了面条' % name)
    time.sleep(1)
    print('%s开始吃面了' % name)
    rlock2.release()   #释放钥匙
    rlock1.release()
def eat2(name):
    rlock2.acquire()
    print('%s拿了面条' % name)
    time.sleep(1)
    rlock1.acquire()
    print('%s拿了叉子' % name)
    time.sleep(1)
    print('%s开始吃面了' % name)
    rlock1.release()
    rlock2.release()

t1=threading.Thread(target=eat1,args=('张一',))
t1.start()
t2=threading.Thread(target=eat2,args=('张二',))
t2.start()
t3=threading.Thread(target=eat1,args=('张三',))
t3.start()
t4=threading.Thread(target=eat2,args=('张四',))
t4.start()

线程信号量--一段代码同时只能n个线程访问:

import threading,time
def func(n,sem):
    sem.acquire()  #上锁
    print('线程%s开始'%n)
    time.sleep(1)
    print('线程%s结束' % n)
    sem.release()    #放锁

sem = threading.Semaphore(3)    #创建信号量,只允许3个线程访问
for i in range(10):
    threading.Thread(target=func,args=(i,sem)).start()

线程事件Event—设置阻塞非阻塞-控制线程:

#一个事件被创建之后,默认是阻塞状态
import threading
e=threading.Event()  #创建一个事件
print((e.is_set()))  #e.is_set()返回事件的状态,False表示处于阻塞状态;True表示处于非阻塞状态。默认阻塞状态
e.set()   #将e.is_set()的状态设置为True非阻塞状态
e.wait()  #是否阻塞。e.is_set()的状态为False就处于阻塞状态;e.is_set()的状态为True就处于非阻塞状态
print('lm')
e.clear()   #将e.is_set()的状态设置为False阻塞状态
e.wait()     #参数 n,表示最多等待n秒,n秒后往下继续执行
print('liming')
#注意:事件在主线程和各子线程之间是共享的
#一个信号可以使所有的线程都进入阻塞状态
#也可以控制所有的线程解除阻塞

条件锁Condition:

import threading
def func(con,i):
    con.acquire()   #上锁
    con.wait()   #等待。线程挂起,直到收到一个notify通知或者超时(可选的,浮点数,单位是秒s)才会被唤醒继续运行。wait()必须在上锁前提下才能调用,否则会触发RuntimeError
    print('第%s个循环'%i)
    con.release()  #释放锁
con=threading.Condition()  #创建条件锁
for i in range(10):
    threading.Thread(target=func,args=(con,i)).start() #启动10个线程
while True:
    num=int(input('请输入数字:'))
    con.acquire()
    con.notify(num)  #通知wait,允许非阻塞num次
    con.release()

延时定时器Timer:

import threading
def func():
    print(100)

t=threading.Timer(3,func)  #创建定时器;参数1 等待n秒后线程开始执行;参数2 要执行的函数,参数3 args/kwargs: 方法的参数
t.start()   #启动定时器
print('结束')

原文地址:https://www.cnblogs.com/liming19680104/p/11670944.html