线程的语法 (event,重要)

Python threading模块

2种调用方式

直接调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import threading
import time
 
def sayhi(num): #定义每个线程要运行的函数
 
    print("running on number:%s" %num)
 
    time.sleep(3)
 
if __name__ == '__main__':
 
    t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
    t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例
 
    t1.start() #启动线程
    t2.start() #启动另一个线程
 
    print(t1.getName()) #获取线程名
    print(t2.getName())

继承式调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import threading
import time
 
 
class MyThread(threading.Thread):
    def __init__(self,num):
        threading.Thread.__init__(self)
        self.num = num
 
    def run(self):#定义每个线程要运行的函数
 
        print("running on number:%s" %self.num)
 
        time.sleep(3)
 
if __name__ == '__main__':
 
    t1 = MyThread(1)
    t2 = MyThread(2)
    t1.start()
    t2.start()

 第二种有点傻

基本语法

is_alive() 当前活跃的线程

例子:

car1 = threading.Thread(target=car,args=('bmw',))
car1.start()
print(car1.is_alive())
if car1.is_alive():
    print('33')
if not car1.is_alive():
    print('444')

执行结果:

bmw wait red light
True
33

例子对比:

car1 = threading.Thread(target=car,args=('bmw',))
# car1.start()   注释掉
print(car1.is_alive()) 
if car1.is_alive():
    print('33')
if not car1.is_alive():
    print('444')

执行结果:

False
444

 

Join ()

等待!其实就wait()。

等待该线程执行完毕

Daemon()

守护进程!有句话怎么说来着!守护进程被吞噬!

# _*_coding:utf-8_*_
import time
import threading

start_time=time.time()
def run(n):
    print('[%s]------running----\n' % n)
    time.sleep(2)
    print('--done--%s'%n)

def run2(n):
    print('[%s]------running----\n' % n)
    time.sleep(5)
    print('--done--%s'%n)
lis_1=[]
t1 = threading.Thread(target=run, args=('run%1',))
t2 = threading.Thread(target=run2, args=('run%2',))

lis_1.append(t1)
lis_1.append(t2)
# t2.setDaemon(True)# 将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务
t1.start()
t2.start()
#  看下就懂了,不懂试一试就想起来了
t1.join()
t2.join()


print("---end time----",time.time()-start_time)

 

线程锁(互斥锁Mutex)

lock()

为什么上锁?因为好多线程同时修改一个数据,有先后顺序,有的没干完,就被gil了,所以对修改数据的地方加把锁,保证该数据的正确性!

lock = threading.Lock() #生成全局锁

不带锁例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import time
import threading
 
def addNum():
    global num #在每个线程中都获取这个全局变量
    print('--get num:',num )
    time.sleep(1)
    num  -=1 #对此公共变量进行-1操作
 
num = 100  #设定一个共享变量
thread_list = []
for in range(100):
    = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)
 
for in thread_list: #等待所有线程执行完毕
    t.join()
 
 
print('final num:', num )

 

带锁例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import time
import threading
 
def addNum():
    global num #在每个线程中都获取这个全局变量
    print('--get num:',num )
    time.sleep(1)
    lock.acquire() #修改数据前加锁
    num  -=1 #对此公共变量进行-1操作
    lock.release() #修改后释放
 
num = 100  #设定一个共享变量
thread_list = []
lock = threading.Lock() #生成全局锁
for in range(100):
    = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)
 
for in thread_list: #等待所有线程执行完毕
    t.join()
 
print('final num:', num )

RLock(递归锁)

这个主要针对函数甲里边包涵函数乙,函数乙又有函数丙

绕进去了,很麻烦,用lock的话容易死循环,所以用Rlock,一键上锁,保证不乱。例子看看就好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import threading,time
 
def run1():
    print("grab the first part data")
    lock.acquire()
    global num
    num +=1
    lock.release()
    return num
def run2():
    print("grab the second part data")
    lock.acquire()
    global  num2
    num2+=1
    lock.release()
    return num2
def run3():
    lock.acquire()
    res = run1()
    print('--------between run1 and run2-----')
    res2 = run2()
    lock.release()
    print(res,res2)
 
 
if __name__ == '__main__':
 
    num,num2 = 0,0
    lock = threading.RLock()
    for in range(10):
        = threading.Thread(target=run3)
        t.start()
 
while threading.active_count() != 1:
    print(threading.active_count())
else:
    print('----all threads done---')
    print(num,num2)

Semaphore(信号量)

互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import threading,time
 
def run(n):
    semaphore.acquire()
    time.sleep(1)
    print("run the thread: %s\n" %n)
    semaphore.release()
 
if __name__ == '__main__':
 
    num= 0
    semaphore  = threading.BoundedSemaphore(5#最多允许5个线程同时运行
    for in range(20):
        = threading.Thread(target=run,args=(i,))
        t.start()
 
while threading.active_count() != 1:
    pass #print threading.active_count()
else:
    print('----all threads done---')
    print(num)

 

Events  

重点,标识符,event可以理解成对全局变量不停的修改,!!!!!!这个我感觉后边能用的到,用event来验证result

语法有

event = threading.Event()

创建标识符

 

event.set( )

设置标识符

 

event.wait( )

等待标识符出现,一旦出现立刻执行后边的代码

print(‘杀啊!!’)
event.wait()
print( ‘撤退!!,杀个瘠薄’

 

event.clear( )

清空标志位

通过Event来实现两个或多个线程间的交互

红绿灯例子!!

import time
import threading

event=threading.Event()

def car(name):
    while True:
        if event.is_set():
            print('%s is runing'%name)
            time.sleep(1)
        else:
            print('%s wait red light' % name)
            event.wait()
            time.sleep(1)

def light():
    conent = 0
    event.set()
    while True:
        if conent >5 and conent <10:
            event.clear()
            print('\033[41;1mred light is on ....\033[0m')
        elif conent >10:
            event.set()
            conent = 0
        else:
            print('\033[42;1mgreen is come!\033[0m')
        time.sleep(1)
        conent += 1

light = threading.Thread(target=light,)

car2 = threading.Thread(target=car,args=('tesla',))


car1 = threading.Thread(target=car,args=('bmw',))
light.start()
car1.start()
car2.start()

运行结果

 

posted @ 2018-06-28 21:12  人无远虑  阅读(172)  评论(0编辑  收藏  举报