设为首页 收藏本站
查看: 825|回复: 0

[经验分享] python多线程基础

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-3-23 09:12:28 | 显示全部楼层 |阅读模式
一、python多线程基础
    python多线程主要涉及两个类:thread和threading,后者实际是对前者的封装,由于threading提供了更完善的锁机制,运用场景更多,重点学习了这个类的使用。
threading.Thread类的使用:
1、在自己的线程类的__init__里调用threading.Thread.__init__(self, name = threadname),threadname为线程的名字
2、 run(),通常需要重写,编写代码实现做需要的功能。
3、getName(),获得线程对象名称
4、setName(),设置线程对象名称
5、start(),启动线程
6、join([timeout]),等待另一线程结束后再运行。
7、setDaemon(bool),设置子线程是否随主线程一起结束,必须在start()之前调用。默认为False。
8、isDaemon(),判断线程是否随主线程一起结束。
9、isAlive(),检查线程是否在运行中。
例子如下:
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
import threading  
import time  

#继承threading.Thread类
class timer(threading.Thread):
    def __init__(self, num, interval):  
        threading.Thread.__init__(self)  
        self.thread_num = num  
        self.interval = interval  
        self.thread_stop = False  
   
   #重新run()方法
    def run(self):
        while not self.thread_stop:  
            print 'Thread Object(%d), Time:%s\n' %(self.thread_num, time.ctime())  
            time.sleep(self.interval)
              
    def stop(self):  
        self.thread_stop = True  
            
def test():  
    thread1 = timer(1, 1)  
    thread2 = timer(2, 2)  
    thread1.start()  
    thread2.start()  
    time.sleep(10)  
    thread1.stop()  
    thread2.stop()  
    return  
   
if __name__ == '__main__':  
    test()



    通常我们通过继承threading.Thread类后重写run方法可以实现我们想做的事情,另一种实现多线程的方法是通过threading.Thread类直接生成线程,同时直接指定线程要执行的方法以及方法相应的参数。见以下例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
import threading

def runTest(x,y):
    for i in range(x,y):
        print i
         
t1 = threading.Thread(target=runTest,args=(15,20))
t2 = threading.Thread(target=runTest,args=(25,35))

t1.start()
t2.start()
t1.join()
t2.join()




二、线程同步
1、简单的同步

    通过锁是实现同步最简单的方式。python的锁对象由thread.Lock类创建。基本流程如下:
1)线程可以使用锁的acquire()方法获得锁,这样锁就进入“locked”状态;
2)每次只有一个线程可以获得锁,如果当另一个线程试图获得这个锁的时候,就会被系统变为“blocked”状态;
3)拥有锁的线程调用锁的release()方法来释放锁,这样锁就会进入“unlocked”状态;
4)“blocked”状态的线程就会收到一个通知,并有权利获得锁。如果多个线程处于“blocked”状态,所有线程都会先解除“blocked”状态,然后系统选择一个线程来获得锁,其他的线程继续沉默(“blocked”)。
    这样一个锁机制存在的问题是,当一个线程获得了锁之后没有释放,又申请了同一个锁资源,此时该线程会进入blocked状态,而且形成死锁。threading.RLock锁原语解决了该问题。RLock对象允许一个线程多次对其进行acquire操作,因为在其内部通过一个counter变量维护着线程acquire的次数。而且每一次的acquire操作必须有一个release操作与之对应,在所有的release操作完成之后,别的线程才能申请该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
import threading  
mylock = threading.RLock()  
num=0  
   
class myThread(threading.Thread):  
    def __init__(self, name):  
        threading.Thread.__init__(self)  
        self.t_name = name  
           
    def run(self):
        #num作为共享资源  
        global num  
        while True:  
            #把共享资源的处理放在acquire()和release()之间
            mylock.acquire()  
            print 'Thread(%s) locked, Number: %d\n'%(self.t_name, num)  
            if num>=4:  
                mylock.release()  
                print 'Thread(%s) released, Number: %d\n'%(self.t_name, num)  
                break  
            num+=1  
            print 'Thread(%s) released, Number: %d\n'%(self.t_name, num)  
            mylock.release()  
               
def test():  
    t1 = myThread('t1')  
    t2 = myThread('t2')  
    t1.start()  
    t2.start()  
   
if __name__== '__main__':  
    test()





2、条件同步——生产者和消费者问题
        当某些条件下才会出现资源竞争的时候就会涉及条件同步。一个形象一点的例子是,伊利牛奶生产厂家可以生产好多牛奶,并将它们放在多个好又多分店进行销售,小明可以从任一间好又多分店中购买到牛奶。只有当厂家把牛奶放在某一分店里,小明才可以从这间分店中买到牛奶。看一下代码描述:
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import threading   
import time  
   
class Producer(threading.Thread):  
   
    def __init__(self, t_name):  
        threading.Thread.__init__(self, name=t_name)  
   
    def run(self):  
        global x  
        con.acquire()
         
        if x > 0:  
            con.wait()
              
        else:  
            for i in range(5):  
                x=x+1  
                print "producing..." + str(x)  
            con.notify()  
  
        print x  
        con.release()  
     
class Consumer(threading.Thread):  
   
    def __init__(self, t_name):   
        threading.Thread.__init__(self, name=t_name)  
   
    def run(self):  
        global x  
        con.acquire()  
   
        if x == 0:  
            print 'consumer wait1'  
            con.wait()
               
        else:  
            for i in range(5):  
                x=x-1  
                print "consuming..." + str(x)  
   
            con.notify()  
   
        print x  
        con.release()  
   
   
   
con = threading.Condition()   
x=0
     
print 'start consumer'   
c=Consumer('consumer')
     
print 'start producer'   
p=Producer('producer')  
     
p.start()   
c.start()  
   
p.join()   
c.join()  
   
print x



据说可以用队列的FIFO特性来实现生产者和消费者问题,后续再学习。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-49620-1-1.html 上篇帖子: python 实现后台cron_table管理 下篇帖子: Python学习之logging模块 python 多线程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表