现在的位置: 首页 > 综合 > 正文

python多线程总结

2013年01月30日 ⁄ 综合 ⁄ 共 3535字 ⁄ 字号 评论关闭
文章目录

多线程总结

话说多线程认识让我恼火了一阵子,很是不习惯程序跳来跳去的执行,毫无时间和空间逻辑的感觉了,现在对我所见的总结一下吧,其实多线程呢在目前的语言中都是差不多,所以只要你理解了多线程在任何语言都是使用的,不同的就是语法不同而已吧 

1. 多线程内幕:

什么是多线程,说白了就是多个线程并发的执行, 既然是并发执行,但是cpu是不可能同时执行多个线程吧,所以怎么办呢,其实是一个假象,由于cpu的时间片轮转的特别快,所以误以为为并发

2. 从1中我们知道了一个问题

就是并发还有cpu轮转就导致线程执行失去了空间和时间顺序,当失去这两个的时候,那么被多线程操作的数据就悲剧了,数据的变化就跟cpu的状态有关了,显然不是很中意的感觉,所以我们引进了锁的概念。什么是锁? 这里的锁不是把线程锁到一个牢房里面而限制这个线程运行, 而相反,当某个线程被锁住了才有执行的权利,否者就是处于阻塞状态,什么是阻塞请看第三点, 既然锁有这个功能,那么我们就可以锁住某个线程,在这个线程被锁住的时间段内,cpu就只处理这个线程, 这样就可以控制时间和空间了,至少这样给了一点儿自己控制的欲望,哈哈

3.什么是阻塞

 
记得一直不理解,现在就总结一下吧。 阻塞的意思就是被阻挡,被阻挡在什么地方呢?这个问题没有人告诉我,也没看到过,结果就我只是意淫吧, 我认为分两种情况,情况一就是这个线程处于锁定池中,那么线程就被阻挡于cpu的门外,只有等 cpu(纯属拟物表达)里面的线程执行完毕才有机会(只是有机会,因为锁定池里面可是一池子的线程等待呀);情况二就是线程压根儿就没有进锁定池,还是处于等待池(这个待会儿解释)中,这个时候离被执行的时间还长着了,就相当于被阻挡于锁定池外吧

4,锁定池是什么呢? 

就是在cpu门外排队的院子,院子里面估计随时都站了很多人。什么是等待池呢?就是连院子都还没有进,就更别说cpu的大门了,只有cpu通知院子外面的人进来他们才能进来5.还谈谈线程同步的问题吧,其实就是上面说的第2点,是靠锁解决6.谈谈什么是线程通讯的问题,也就是上面谈得连院子都还没进的人什么时候进入院子的事儿。这个问题转化为正在执行的这个线程在cpu中执行完之后标记一个条件变量(就一变量),这个变量就是通知院子外的线程可以升级了,在院子里面来接着等吧(呵呵)

5.这个地方还有我另外一段的总结, 放这里吧,相信对你也是有帮助的:


线程总结2:

1.线程是分为五种状态的, 新建,就绪,运行,阻塞,死亡
2.为了使数据同步,所以有了线程同步(就是当数据是一个共享数据时,将数据锁住,只允许锁定这个数据的线程使用,别的线程处于等待状态
(就是阻塞状态))这个功能
3. 数据能被线程操作就必须得现有数据(必须的),如果数据是由线程一在运行后创建的, 那么线程二,三,四...就只能等线程一先执行后才能
执行(否则就没有供线程2,3,4...操作的数据),为了达到让线程先后执行的目的就引入了线程之间的通讯机制,也就是设一个条件变量,只
有当 线程一执行后设定条件变量为可行(我感觉是自己(线程一)执行完毕)时,此时等待池(此处线程状态为等待)里面的线程才能进入
锁定池 (此时线程为暂停,或者是阻塞)变为阻塞状态
4. 这一点是对3的一个更正, 以前对3是理解不清楚的,其实等待池和锁定池里面的进程都是阻塞的,下面引入一个大牛的回复:
技术上处于等待池和锁定池中的线程都是传统意义上的阻塞状态,只不过为不同的对象所阻塞而已。
等待池是等待一个事件的发生(条件变量),比如等待磁盘I/O的完成,等I/O完成后,会通知一个或全部之前等待的线程,于是这些线程进
入锁定 池,同样也是阻塞状态。为什么不直接进入运行状态(已锁定)?因为所有线程共享一个mutex/lock,只有锁定池中的一个可以线
程幸运的获得 锁,进入已锁定状态。所以,等待池中的线程等的是条件变量的触发,锁定池中的线程等的是获得共享锁。这些都是条件变
量的特点。

哈哈,下面这个例子一...告诉我的例子,话糙理不糙呀:
举个少儿不宜的例子,等待池中的线程就像爸爸身体里的上亿个精子,蠢蠢欲动等待爸爸妈妈结合的那一刻 ---> 爸爸妈妈结合的那一刻,精
子们终于等到了通知,一个激动全部冲入妈妈的肚子里,此时进入等待锁定池,等待着和妈妈的卵子结合! ---> 最终只有一个幸运的精子可
以得到卵子的垂青,结合在一起!此时就是已锁定状态!







此线以后就是跟python有关了




1.python的time.sleep(val)是干什么的呢

可不是网上很多没说清楚的使主线程睡眠val秒,而是这句处于哪个正在执行的线程代码中,那么这个线程就得睡眠val秒,睡眠的意思就是睡觉休
息了,休息了的这段时间cpu课不能闲着呀, 还得去执行别的线程,等休息了val秒后接着执行(个人感觉别的线程可不是那么容易的将执行权还
给这个线程,应该会拖拖拉拉的)

2. thread模块只能提供简单的锁

很多缺点我不说了,除非你是绝对的高手,否则还是别玩这个了,玩另一个吧

3.threading,高度成熟的一个库

  在thread基础上封装了很多高级的类

下面我着重介绍一下threading模块的使用:

三种不同的创建线程方法

方法1:

就是直接用像thread模块一样吧,传入一个函数,这里就不给出源码了

方法2:

用面向对象的模式创建一个线程实例,说白了就是不再是给线程传递一个将要执行的函数了,而是传递一个实例对象,你在想一个对象里面类么多方法,究竟要执行类里面的哪一个方法呢?这个问题看实例吧
#encode:utf-8
import thread
import threading
import time


def ClassFunc(object):
    def ___init__(self, func, args, name):
        self.name = name
        self.func = func
        self.args = args
    
    def __call__(self):
        apply(self.func, self.args, self.name)
loops = [2, 4]

def loop(n, nsec):
    print 'loop ', n, 'start at :', time.time()
    time.sleep(nsec)
    print 'loop ', n, 'done at :', time.time()

def main():
    nloops = range(len(loops))
    threads = []
    for i in nloops:
        print nloops[i]
        t = threading.Thread(target = loop, args = (i, loops[i]))
        threads.append(t)

    print 'all loop start at:', time.time()
    for i in threads:
        i.start()

    for i in threads:
        i.join()
    print 'all loop done at:', time.time()

if __name__ == '__main__':
    main()

上面的问题答案就是将自动调用方法__call__,这个方法就是为线程专门设计,大家也看到了__call__这个方法里面有一条apply(...)了吧,其实这个函数的作用就是调用存于元组或者字典里面的方法,现在self.func, self.args, self.name 里面就是一个完整的方法,有方法名,参数列表,线程名字

方法3:

#coding=gbk
import threading, time, random
count = 0
class Counter(threading.Thread):
    def __init__(self, lock, threadName):
        '''@summary: 初始化对象。
        
        @param lock: 琐对象。
        @param threadName: 线程名称。
        '''
        super(Counter, self).__init__(name = threadName)
        self.lock = lock
    
    def run(self):
        '''@summary: 重写父类run方法,在线程启动后执行该方法内的代码。
        '''
        global count
        self.lock.acquire()
        for i in xrange(100000000):
            count = count + 1
        self.lock.release()
lock = threading.Lock()
for i in range(5): 
    Counter(lock, "thread-" + str(i)).start()
time.sleep(5)
print count

方法三代码引用自:http://blog.csdn.net/jgood/article/details/4305604,解释看这里吧
未完待续

抱歉!评论已关闭.