多线程

简介:

进程 pid 唯一标示符

使用kill杀死进程


主线程 创造一个进程的时候,会创造一个线程,这个线程被称为主线程

一个进程只有一个主线程


python里的多线程,不是真正意义上的多线程,只是多线程的假象

全局锁GIL 在任意的指定时间里,有且只有一个线程在运行——>python是线程安全的


1
2
3
4
5
import  threading
def  test():
     print  1
a = threading.Thread(target = test)
a.start()

  

1
2
3
4
5
6
7
8
9
import  threading
def  test():
     print  1
a = threading.Thread(target = test)
b = threading.Thread(target = test)
a.start()
b.start()
a.join()
b.join()


1
2
3
4
5
6
7
8
9
10
11
12
13
import  threading
import  time
def  test():
     time.sleep( 0.001 )
     print  1
ts = []
for  in  xrange ( 0 , 15 ):
     th = threading.Thread(target = test,args = [i])
     th.start()
     ts.append(th)
for  in  ts:
     i.join()    ##等待线程结束后,继续运行脚本
print  "End"


日常推荐使用多进程,而不是多线程。多线程复杂度较高,可维护性差,且只是在使用单个CPU。


一个程序的复杂度,大部分情况下,只和代码行数有关。


在数据库连接池的场景下,可以使用多线程


io操作作用到多线程?必须要lock,acquire,release

互斥锁

加锁      acquire

释放锁    release

加锁一定要释放,不释放成死锁


1
2
3
4
5
6
7
8
9
10
11
12
import  threading
mlock = threading.Lock()
num = 0
def  a():
     global  num
     mlock.acquire()
     num + = 1
     mlock.release()
     print  num
for  in  xrange ( 0 , 10 ):
     d = threading.Thread(target = a)
     d.start()


rlock 防止死锁


协程

包含yield的函数,则是一个可迭代对象

  利用next方法,取每一次yield

  send方法

生产者,消费者行为

无需立即执行,需要时才执行

1
2
3
4
5
6
7
8
def  test():
     i = 0
     a = 4
     while  i<a:
         x = yield  i
         i + = 1
t = test()
print  t. next ()

【扩展阅读1】

  多线程向来是一个让程序员头痛的一个问题,不只是初学者容易犯错误,很多老鸟也难免站着中枪。一旦出现问题很难定位和解决,除了可能因为编程者知识上的缺陷导致的疏漏外,另一个难题就是问题重现难度大,避免多线程导致BUG最好的方法就是预防。

  首先,在开始进行多线程编程之前要考虑好,我们是否真的需要多线程,什么时候才需要多线程。正所谓”大道至简“,越简单的设计越是好的设计,如果单个线程就可以完成任务解决问题,就不要用多个线程,不要为了炫耀一下自己的多线程编程能力动不动就起个线程,到最好搞不好会搬石头砸自己的脚。那什么情况下才需要用多线程呢,如果满足以下两个条件之一就不得使用多线程:
(1)单线程不能满足业务需要。例如12306的火车票售票系统,在同一时间内可能会有NNN个请求,这些请求之间是完全独立的,其发起时间也是没有相互依赖关系的,后台必须使用多线程处理以保证对用户响应的及时。

  (2)单线程不能满足性能要求且数据IO吞吐率低于CPU的处理能力。如果单个线程可以满足性能要求根据无须考虑多线程了,在对于访问IO较多的应用中,IO(无论是读写数据还是等待用户响应)会阻塞线程的运行,而CPU更多的时间处于等待外部响应的状态,此时增加线程可以提高CPU的利用率,当有线程在等待IO的时候有别的线程在使用CPU,从而通过提高CPU的利用率而提高应用的整体性能。

  其次,当确定了肯定要用多线程之后,紧接着就得考虑一个问题:用几个线程比较合适?主要可以从以下方面考虑:

  (1)业务逻辑。根据实际的业务不同要通过经验数据来确定线程的数量,很难有统一的公式计算出来,要通过不断的调整、测试、比较来确定一个比较合理的数字,而且随着业务的变更,参数还要重新调整。

  (2)CPU数量。如果只有一个CPU,在同一时间不可能执行两个线程的,它们是通过时间片的轮换来实现多线程的,而在线程间的不断切换时操作系统会有进行很多的操作,相当消费CPU资源,线程越多无谓的CPU消费也就越多。对于一个计算密集型的任务可能只用一个线程才是效率最高的,例如对大块内存数据的排序操作,没有任何IO会阻塞线程,使用多个线程只会无谓地消费CPU资源,只需要一个线程一直进行排序操作即可。要想发挥CPU的最佳性能,无论对任何类型的应用,线程的最小数量就是CPU的数量,如果此时CPU还有空闲再考虑增加线程的数量,不断调整以取得最佳的性能。

  (3)内存大小。因为每个线程都要分配独立的栈以及独立的上下文环境,所以创建一个新的线程之后即使什么也不干也会消耗一定的内存,故而并不是线程越多性能越好。因为如果创建的线程过多内存不够用,很可能导致程序在运行过程中有虚拟内存的使用,将内存的访问转化为低速存储的访问,反而会负面影响应用的性能。

  然而,这些因素只是影响确定线程数的重要因素,但并没有公式可使用,需要根据经验对这些因素进行评估并通过试验来确定最佳的线程数。


【扩展阅读2】

在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上。














本文转自Grodd51CTO博客,原文链接:http://blog.51cto.com/juispan/1970411,如需转载请自行联系原作者


相关文章
|
9月前
|
安全 Java
多线程02
多线程02
|
2月前
|
Web App开发 IDE Java
什么是多线程
什么是多线程
26 3
|
2月前
|
Java API 调度
多线程知识篇
多线程知识篇
|
2月前
|
Java API 调度
多线程 02
多线程 02
22 0
|
Linux 调度
多线程具体实现(上)
多线程具体实现
65 0
|
调度
多线程之争用条件
多线程之争用条件
134 2
多线程之争用条件
|
Java Linux 调度
多线程必知必记的
《基础系列》
116 0
多线程必知必记的
|
缓存 安全 Java
多线程具体实现
多线程具体实现
|
Java 调度 C#
C# 多线程
多线程: 进程可以包括若干个线程,同时创建多个线程来完成某项任务,就可以称之为多线程
75 0
|
算法 Java 调度
多线程二 基本技能
多线程二 基本技能
103 0