Python的 并发、并行

记录:

并发:在一个时间段,处理多个任务,单核也可以并发(CPU分时间片);

并行:在同一个时刻,处理多个任务,必须多核才能并行;

一、Python实现并发的手段:

1、操作系统提供:进程、线程;

2、编程语言提供:协程:用户空间的调度(py3);

题外话:

现在的操作系统,进程和线程的区别越来越小,因为进程越来越轻了;实际上,Linux的线程是通过进程实现的;

二、Python的进程和线程的区别:

Python每个进程都会启动一个解释器;

Python每个线程(一个进程下面的)共享一个解释器;

ps:Python没有提供主动停止线程的方法的;只能等线程处理完毕,或者主线程结束;所以在线程逻辑里面一定要写退出逻辑;

三、logging库:

通常用logging代替print,因为logging是线程安全的,在多线程下,输出表现正常,而print是非线程安全的,在多线程下,输出表现会出现异常,例如,T1没输出完毕,T2又进行输出了;

四、Python 线程的 daemon 属性:

默认是false;

daemon:守护、守护进程;

守护进程:Daemon()程序是一直运行的服务端程序,又称为守护进程。通常在系统后台运行,没有控制终端,不与前台交互,Daemon程序一般作为系统服务使用。Daemon是长时间运行的进程,通常在系统启动后就运行,在系统关闭时才结束。

知识点一:

当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在python中,默认情况下(其实就是setDaemon(False)),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束;

知识点二:

当我们使用setDaemon(True)方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止;

知识点三:

join所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞(等待)状态,一直等待其他的子线程执行结束之后,主线程在终止;

知识点四:

join有一个timeout参数:

当设置守护线程时,含义是主线程对于子线程等待timeout的时间将会杀死该子线程,最后退出程序。所以说,如果有10个子线程,全部的等待时间就是每个timeout的累加和。简单的来说,就是给每个子线程一个timeout的时间,让他去执行,时间一到,不管任务有没有完成,直接杀死。

没有设置守护线程时,主线程将会等待timeout的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。

t1.join(),子线程设置这个就是让主线程阻塞(等待),那么在哪里设置了 t1.join(),主线程就在这里等待t1执行完毕,再继续往下执行;因为两个线程顺序完成,看起来象一个线程,所以称为线程的合并,其实也是让线程同步了;

注意(看到的结果是这样,解释可能不太正确):

(1)看图:

t1设置执行2秒;t2设置执行3秒;目的是为了t1先于t2执行完毕;

t1没有设置daemon线程,所以当主线程结束后,t1仍然会继续执行完毕,所以查看结果:当输出 main end ... 后,仍然有 t1 out ... 输出;

t2设置为daemon线程,所以当主线程结束后,t2也被主线程杀死了(t1已结执行完毕),跟着结束了,程序(进程)也结束了,所以没有 t2 out... 输出;

注意,这里一定要保证t1(非daemon子线程)先于t2执行完毕;因为如果t1要比t2耗时长的话,因为 t1是非daemon子线程,即是主线程结束了,t1仍然要继续执行的,所以整个程序(进程)并不会结束,也就没有杀死t2,导致t2也会执行完毕;看下面:

可以看到:即是t2是daemon子线程,但是仍然执行完毕了,并没有因为主线程的退出而被杀死,因为t1的执行时间比t2长;

ps:如果不是以继承的方式创建线程,那么run方法和start方法只能执行其中一个;通常也不建议使用继承的方式;start方法是子线程执行的,启动子线程;

要注意:主线程、父线程、子线程的关系;

五、Python中的ThreadLocal变量

注意,并不是子线程要执行的目标函数里面的局部变量,虽然每个线程即使是执行同一个函数,都会有自己的内存的,互不干扰,但是函数里面的局部变量,就是属于函数的,到了另外一个函数不会认识此局部变量;

而Python的threadlocal变量,是属于线程的,此线程调用的所有函数都认识threadlocal变量,eg.:

global_data = threading.local()

def show():

        print (threading.current_thread().getName(), global_data.num

def thread_cal():

        global_data.num = 0

        for _ in xrange(1000):

            global_data.num += 1

        show()

每个线程都可以通过 global_data.num 获得自己独有的数据,并且每个线程读取到的 global_data 都不同,真正做到线程之间的隔离。其他线程是不认识global_data.num的;

六、线程同步方式(前三个方式需要在具体了解)

线程的同步,有一层意思就是:线程之间的通讯,线程总是有某种关联,才需要同步的,而同步就意味着阻塞(等待);

1、event

两个线程之间事件的通知,我发现了一个事件,set,你就可以查看。

2、lock (rlock?)

保护共享资源;

3、condition

生产者消费者模式;生产者唤醒消费者;


4、Barrier(栅栏)

就是线程们在等待,直到线程数满足设定的数量之和,才继续执行;

可以使用此方法开发并发测试工具;

一些关键语句:

barrier = threading.Barrier(3)  #等齐3个线程

worker_id = barrier.wait()  #线程执行到这一句,就等着,满足数量之后,再往下走

barrier.n_waiting  #现在在等待的线程数量

barrier.abort()  #通知已经在等待的线程,不必再等了,我执行不到wait()了(任何一个线程执行都可以),当abort()方法被执行,wait()方法就会抛出异常

5、semaphore (信号量)

s = threading.Semaphore(2)

s.acquire() # 获得,在线程中,也是锁住某个变量,自己此刻独占;

输出:True  # 成功锁住

s.acquire(False) # 再来一次

输出:True  # 成功锁住

s.acquire(False) # 再来一次

输出:False # 没有锁

锁是信号量的特例:为1的信号量;

信号量也是对共享资源的保护,但是和锁不一样,锁限制只有一个线程可以访问共享资源,而信号量限制指定个线程可以访问共享资源;所以信号量可以用于做连接池的功能;

七、异步编程

1、概念

同步、异步:

发生在函数调用的时候,是否得到直接最终结果;

得到直接最终结果的是:同步调用;

不得到直接最终结果的是:异步调用;

阻塞、非阻塞:

发生在函数调用的时候,是否立刻返回;

立刻返回:非阻塞调用;

不立刻返回:阻塞调用;

ps:同步、异步 与 阻塞、非阻塞 在概念上是不相关的;

同步、异步:关注的是结果;

阻塞、非阻塞:关注的是是否等待;

ps:异步非阻塞是最好的性能咯;

同步IO、异步IO、IO多路复用:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。我们前面提到了进程是由若干线程组成的,一个进程至少有一个线...
    壁花烧年阅读 810评论 0 0
  • “快跳!跳一线天,捡枪就干,刚刚这帮人喊的可带劲了,清掉他们!” “老板来桶泡面,老坛酸菜的,还是不要油包!” “...
    Lucifer_陶阅读 242评论 2 1
  • 亲爱的周周: 你好! 通过十月一号的行走到今天十月十号的行走,目前我在qq和支付宝行走捐里已经积累捐赠30块钱了,...
    真爱521阅读 163评论 0 0
  • 黄昏,侯三走到了半山腰,离家还有二十多里的山路,天黑之前铁定赶不回去了,侯三开始担心起来,这前不着村后不着店的,万...
    探微游尘阅读 734评论 2 6
  • 被“双宋”满屏的喜糖喂得酒足饭饱之后,相信不少人都开始二刷“太阳的后裔”,回味于这段医生与军人之间从银幕走向现实的...
    知寒XY阅读 463评论 0 1