线程2

一,守护线程

守护线程和守护进程是一样的,都是随着主进程或者主线程的结束而结束

复制代码
from threading import Thread
import time
def func():
    print('22')
    time.sleep(1)
    print('22')


t=  Thread(target=func)
t.setDaemon(True)
t.start()
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
22

Process finished with exit code 0

当我们再起一个线程时:

复制代码
from threading import Thread
import time
def func():
    print('11')
    time.sleep(1)
    print('22')


t=  Thread(target=func)
t.setDaemon(True)
t.start()
t1=  Thread(target=func)

t1.start()
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
11
11
22
22

Process finished with exit code 0

二,线程的锁

复制代码
from threading import Thread
from threading import Lock
import time
def func():
    global n
    time.sleep(1)
    # l.acquire()
    n-=1
    # l.release()


n=10
l=Lock()
l1=[]
for i in range(10):
    t=Thread(target=func)
    t.start()
    l1.append(t)
[t.join() for t in l1]
print(n)
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
0

Process finished with exit code 0

有种特殊情况:

复制代码
from threading import Thread
from threading import Lock
import time
def func():
    global n
    time.sleep(1)
    # l.acquire()
    tt=n                  #从进程中获取值
    time.sleep(1)
    n=tt-1                 #再返回进程
    # l.release()


n=10
l=Lock()
l1=[]
for i in range(10):
    t=Thread(target=func)
    t.start()
    l1.append(t)
[t.join() for t in l1]
print(n)
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
9

Process finished with exit code 0

这种情况还是要加锁的:

复制代码
from threading import Thread
from threading import Lock
import time
def func():
    global n
    time.sleep(1)
    l.acquire()
    tt=n
    time.sleep(1)
    n=tt-1
    l.release()


n=10
l=Lock()
l1=[]
for i in range(10):
    t=Thread(target=func)
    t.start()
    l1.append(t)
[t.join() for t in l1]
print(n)
复制代码

GIL锁的不是数据,而是线程

 

三,死锁

复制代码
from threading import RLock
from threading import Thread
from threading import Lock
import time
a=Lock()
b=Lock()

def kill(name):
    a.acquire()
    print('%s拿到枪了'%name)
    b.acquire()
    print('%s拿到子弹了'%name)
    print('%s杀人了' % name)
    b.release()
    a.release()

def kill1(name):
    b.acquire()
    print('%s拿到子弹了' % name)
    time.sleep(1)
    a.acquire()
    print('%s拿到枪了' % name)
    print('%s杀人了' % name)
    a.release()
    b.release()

Thread(target=kill,args=('二狗',)).start()
Thread(target=kill1,args=('大狗',)).start()
Thread(target=kill,args=('三狗',)).start()
Thread(target=kill1,args=('四狗',)).start()
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
二狗拿到枪了
二狗拿到子弹了
二狗杀人了
大狗拿到子弹了
三狗拿到枪了

这就是死锁现象了,怎么解决这个问题呢?

复制代码
from threading import RLock
from threading import Thread
from threading import Lock
import time
b=a=RLock()


def kill(name):
    a.acquire()
    print('%s拿到枪了'%name)
    b.acquire()
    print('%s拿到子弹了'%name)
    print('%s杀人了' % name)
    b.release()
    a.release()

def kill1(name):
    b.acquire()
    print('%s拿到子弹了' % name)
    time.sleep(1)
    a.acquire()
    print('%s拿到枪了' % name)
    print('%s杀人了' % name)
    a.release()
    b.release()

Thread(target=kill,args=('二狗',)).start()
Thread(target=kill1,args=('大狗',)).start()
Thread(target=kill,args=('三狗',)).start()
Thread(target=kill1,args=('四狗',)).start()
复制代码
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
二狗拿到枪了
二狗拿到子弹了
二狗杀人了
大狗拿到子弹了
大狗拿到枪了
大狗杀人了
三狗拿到枪了
三狗拿到子弹了
三狗杀人了
四狗拿到子弹了
四狗拿到枪了
四狗杀人了

Process finished with exit code 0
复制代码

用RLock就可以解决这个问题了

lock是互斥锁

RLock是递归锁

 

四  信号量

复制代码
from threading import Thread
from threading import Semaphore
import time
import random

def func(i,sem):
    sem.acquire()
    print('我是%s'%i)
    time.sleep(random.random())
    print('我是%s'%i)

sem=Semaphore(5)
for i in range(10):
    Thread(target=func,args=(i,sem)).start()
复制代码
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
我是0
我是1
我是2
我是3
我是4
我是3
我是4
我是1
我是2
我是0
复制代码

信号量和线程池的区别,信号量是一次就显示这些线程,而线程池是每次就开这么多线程

五,事件

复制代码
from threading import Event
from threading import Thread
from threading import Semaphore
import time
import random

def func():
    count = 1
    while not e.is_set():  # 当事件的flag为False时才执行循环内的语句
        if count > 3:
            raise TimeoutError
        print('尝试连接第%s次' % count)
        count += 1
        e.wait(0.5)  # 一直阻塞变成了只阻塞0.5
    print('连接成功')  # 收到check_conn函数内的set指令,让flag变为True跳出while循环,执行本句代码


def check_conn():
    '''
    检测数据库服务器的连接是否正常
    '''
    time.sleep(random.randint(1, 2))  # 模拟连接检测的时间
    e.set()  # 告诉事件的标志数据库可以连接


e = Event()
check = Thread(target=check_conn)
check.start()
conn = Thread(target=func)
conn.start()
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
尝试连接第1次
尝试连接第2次
连接成功

Process finished with exit code 0

六,,条件

复制代码
import threading

def func(i):
   t.acquire()
   t.wait()
   print('hello%s'%i)
   t.release()




if __name__=='__main__':
    t=threading.Condition()#条件,锁加wait()功能
    for i in range(10):
        threading.Thread(target=func,args=(i,)).start()

    while 1:
        info=input('>>>')
        if info=='q':
            break
        t.acquire()
        if info=='all':
            t.notify_all()
        else:
            t.notify(int(info))

        t.release()
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
>>>2
>>>hello0
hello1

根据你设定的条件,设定每次执行多少线程

七,定时器

from threading import  Timer
def func():
    print('hello')
Timer(4,func).start()
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
hello

Process finished with exit code 0

八,队列

复制代码
import queue
t=queue.LifoQueue()
t.put(1)
t.put(2)
t.put(3)
print(t.get())





C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
3

Process finished with exit code 0
复制代码

后进先出

复制代码
import queue
t=queue.PriorityQueue()
t.put((1,'q'))
t.put((4,'e'))
t.put((3,'g'))
t.put((3,'o'))
print(t.get())
print(t.get())
print(t.get())
print(t.get())
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
(1, 'q')
(3, 'g')
(3, 'o')
(4, 'e')

Process finished with exit code 0
# 值越小越优先,值相同就asc码小的先出

 

九,concurrent

 

复制代码
import time
import random
from concurrent import futures
def func(n):
    print(n)
    time.sleep(random.randint(1,3))
    return n*'*'
def fu(c):
    print(c.result())
f=futures.ThreadPoolExecutor(3)#线程池
f.submit(func,2)#submit=start
复制代码
C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
2

Process finished with exit code 0

 

 

返回值:

复制代码
import time
import random
from concurrent import futures
def func(n):
    print(n)
    time.sleep(random.randint(1,3))
    return n*'*'
def fu(c):
    print(c.result())
f=futures.ThreadPoolExecutor(3)#线程池
t=f.submit(func,2)#submit=start
print(t.result())#result打印返回值


C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
2
**

Process finished with exit code 0
复制代码

 

 

复制代码
import time
import random
from concurrent import futures
def func(n):
    print(n)
    time.sleep(random.randint(1,3))
    return n*'*'
def fu(c):
    print(c.result())
f=futures.ThreadPoolExecutor(3)#线程池
l=[]
for i in range(10):
    t=f.submit(func,i)#submit=start
    l.append(t)
f.shutdown()#相当于close()和join()集合体
for i in l:
    print(i.result())


C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
0
1
2
3
4
5
6
7
8
9

*
**
***
****
*****
******
*******
********
*********

Process finished with exit code 0
复制代码

 

 

 

 

回调:

复制代码
import time
import random
from concurrent import futures
def func(n):
    # print(n)
    time.sleep(random.randint(1,3))
    return n*'*'
def fu(c):
    print(c.result())
f=futures.ThreadPoolExecutor(3)#线程池
l=[]
for i in range(10):
#     t=f.submit(func,i)#submit=start
#     l.append(t)
# f.shutdown()#相当于close()和join()集合体
# for i in l:
#     print(i.result())

    f.submit(func,i).add_done_callback(fu)#回调







C:\Users\hc\AppData\Local\Programs\Python\Python36\python3.exe C:/s9/day39/39.py
**

*
*****
***
****
******
********
*********
*******

Process finished with exit code 0
复制代码

 

posted @   许光宗  阅读(113)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示