python的多线程,python多线程有几种实现方法

1,python多线程有几种实现方法基本上有两种,第一种是继承Thread类 , 然后重写run方法,来实现新线程类的创建 。第二种是写一个类实现Runnable()接口,然后将这个类传给一个Thread对象来创建线程对象 。这两种方法本质是一样的 。因为Thread类也实现了Runnable接口 。python 的gil规定每个时刻只能有一个线程访问python虚拟机,所以你要用python的多线程来做计算是很不合算的,但是对于io密集型的应用 , 例如网络交互来说,python的多线程还是非常给力的 。如果你是一个计算密集型的任务,非要用python来并行执行.【python的多线程,python多线程有几种实现方法】
2,python 多线程状态threading.active_count()Return the number of Thread objects currently alive. The returned count is equal to the length of the list returned by enumerate().active_count可以返回当前活动的线程枚举我一般是这么用的 def getHeatsParallel(self): threads = [] for i in range(0, self.threadCount): t = threading.Thread(target=self.SomeFunction, name=str(i)) threads.append(t) t.start() for t in threads: t.join()不过我不关心几个活动,因为指定最多就是threadCount个线程谁说python多线程支持不好,比起ruby,比起perl , 好的不要太多 。python有很多实现多线程的方法:1.挂锁2.queue 队列3.信号机也可以自己构建循环缓冲区我自己总结的构建线程的一些思路:抽象出共享空间,就是读线程和写线程均要访问的那块区域--临界区域,在这个对象里面设置读方法和写方法 , 并挂锁 , 也就说不能有2个或者2个以上的线程同时操作共享区域,挂锁 的时候注意死锁问题 。这就是基本的线程同步了,如果要加上缓冲就要考虑记录每个线程操作到什么位置,就是位置信息 。代码不贴了 , 看我blog里面有几个写python的http://hi.baidu.com/linuxbird只要记得几个思路就可以了
3,Python如何跑多线程Python多线程运行:使用线程可以把占据长时间的程序中的任务放到后台去处理 。用户界面可以更加吸引人 , 百这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度程序的运行速度可能加快在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了 。在这种情况下我们可以释放一些珍贵的资源如内存占用等等 。线程在执行过程中与进程还是有区别的 。每个独立的线程有一个度程序运行的入口、顺序执行序列和程序的出口 。但是线程不能够独立执行 , 必须依存在应用程序中,由内应用程序提供多个线程执行控制 。每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态 。指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些容地址都用于标志拥有线程的进程地址空间中的内存 。线程可以被抢占(中断) 。在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) -- 这就是线程的退让 。在python里线程出问题,可能会导致主进程崩溃 。虽然python里的线程是操作系统的真实线程 。那么怎么解决呢?通过我们用进程方式 。子进程崩溃后 , 会完全的释放所有的内存和错误状态 。所以进程更安全 。另外通过进程,python可以很好的绕过gil,这个全局锁问题 。但是进程也是有局限的 。不要建立超过cpu总核数的进程,否则效率也不高 。简单的总结一下 。当我们想实现多任务处理时,首先要想到使用multiprocessing, 但是如果觉着进程太笨重,那么就要考虑使用线程 。如果多任务处理中需要处理的太多了,可以考虑多进程,每个进程再采用多线程 。如果还处理不要,就要使用轮询模式,比如使用poll event, twisted等方式 。如果是gui方式 , 则要通过事件机制,或者是消息机制处理 , gui使用单线程 。所以在python里线程不要盲目用 ,  也不要滥用 。但是线程不安全是事实 。如果仅仅是做几个后台任务,则可以考虑使用守护线程做 。如果需要做一些危险操作,可能会崩溃的 , 就用子进程去做 。如果需要高度稳定性,同时并发数又不高的服务 。则强烈建议用多进程的multiprocessing模块实现 。在linux或者是unix里,进程的使用代价没有windows高 。还是可以接受的 。
4,为什么有人说 Python 的多线程是鸡肋因为python的全局解释器锁(global interpreter lock , gil)强制要求python只能在一个解释器中进行,也就是说即使你有多个处理器,python也只能使用其中的一个 , 线程实际上是在串行运行 。如果只有一个处理器,那么python的线程和其他语言没什么区别 , 但如果有两个及以上就不同了,其他语言可以使用所有处理器,但python只能使用一个 。假如在单核处理器中,python的效率可以达到百分之百,那么在双核处理器中,它的效率只有百分之五十 , 因为它只能使用一个处理器 , 另一个是闲置的,效率并没有因为多了一个处理器而得到提高,所以说python的多线程有点鸡肋 。除非可以去除gil , 否则应该尽量避免使用python的多线程 。注:另外很多任务是可以用python的协程来完成的,用协程来代替多线程是个不错的选择差不多是这样子 。多线程目前仅用于网络多线程采集,以及性能测试 。其它的语言也有类似的情况,线程本身的特点导致线程的适用范围是受限的 。只有CPU过剩 , 而其它的任务很慢,此时用线程才是有益的 , 可以很好平衡等待时间,提高并发性能 。线程的问题主要是线程的安全稳定性 。线程无法强制中止,同时线程与主进程共享内存,可能会影响主进程的内存管理 。在python里线程出问题,可能会导致主进程崩溃 。虽然python里的线程是操作系统的真实线程 。那么怎么解决呢?通过我们用进程方式 。子进程崩溃后,会完全的释放所有的内存和错误状态 。所以进程更安全 。另外通过进程,python可以很好的绕过GIL,这个全局锁问题 。但是进程也是有局限的 。不要建立超过CPU总核数的进程,否则效率也不高 。简单的总结一下 。当我们想实现多任务处理时,首先要想到使用multiprocessing,但是如果觉着进程太笨重,那么就要考虑使用线程 。如果多任务处理中需要处理的太多了,可以考虑多进程 , 每个进程再采用多线程 。如果还处理不要,就要使用轮询模式 , 比如使用poll event, twisted等方式 。如果是GUI方式,则要通过事件机制,或者是消息机制处理,GUI使用单线程 。所以在python里线程不要盲目用,也不要滥用 。但是线程不安全是事实 。如果仅仅是做几个后台任务,则可以考虑使用守护线程做 。如果需要做一些危险操作,可能会崩溃的 , 就用子进程去做 。如果需要高度稳定性,同时并发数又不高的服务 。则强烈建议用多进程的multiprocessing模块实现 。在linux或者是unix里,进程的使用代价没有windows高 。还是可以接受的 。Python多线程是不是鸡肋,是,GIL那个东西再那里摆着,就算在多核下面Python也是无法并行的,这个好理解嘛 , 就相当于做了个分时复用 。Python多线程有没有用,有,你去爬图片站的时候,用单进程单线程这种方式,进程很容易阻塞在获取数据socket函数上,多线程可以缓解这种情况 。你说解决没有,要是每个请求都阻塞起了,那多线程也没什么用(当然,这种情况没见过哈) 。Python的优势就在于写起来快,用起来方便 。你要做计算密集型的,还想并行化的话,还是用C吧 。5,python多线程几种方法实现Python进阶(二十六)-多线程实现同步的四种方式临界资源即那些一次只能被一个线程访问的资源,典型例子就是打印机,它一次只能被一个程序用来执行打印功能,因为不能多个线程同时操作,而访问这部分资源的代码通常称之为临界区 。锁机制threading的Lock类,用该类的acquire函数进行加锁,用realease函数进行解锁import threadingimport timeclass Num:def __init__(self):self.num = 0self.lock = threading.Lock()def add(self):self.lock.acquire()#加锁,锁住相应的资源self.num += 1num = self.numself.lock.release()#解锁 , 离开该资源return numn = Num()class jdThread(threading.Thread):def __init__(self,item):threading.Thread.__init__(self)self.item = itemdef run(self):time.sleep(2)value = http://www.lisdn.com/mnsj/hhzs/n.add()#将num加1,并输出原来的数据和+1之后的数据print(self.item,value)for item in range(5):t = jdThread(item)t.start()t.join()#使线程一个一个执行12345678910111213141516171819202122232425262728当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态 。每次只有一个线程可以获得锁 。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态 , 称为“同步阻塞”(参见多线程的基本概念) 。直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态 。线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态 。信号量信号量也提供acquire方法和release方法,每当调用acquire方法的时候,如果内部计数器大于0,则将其减1,如果内部计数器等于0,则会阻塞该线程,知道有线程调用了release方法将内部计数器更新到大于1位置 。import threadingimport timeclass Num:def __init__(self):self.num = 0self.sem = threading.Semaphore(value = 3)#允许最多三个线程同时访问资源def add(self):self.sem.acquire()#内部计数器减1self.num += 1num = self.numself.sem.release()#内部计数器加1return numn = Num()class jdThread(threading.Thread):def __init__(self,item):threading.Thread.__init__(self)self.item = itemdef run(self):time.sleep(2)value = n.add()print(self.item,value)for item in range(100):python 的gil规定每个时刻只能有一个线程访问python虚拟机,所以你要用python的多线程来做计算是很不合算的,但是对于io密集型的应用,例如网络交互来说,python的多线程还是非常给力的 。如果你是一个计算密集型的任务,非要用python来并行执行.

    推荐阅读