线程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 @ 2018-02-07 22:27  许光宗  阅读(112)  评论(0编辑  收藏  举报