join控制子进程
我们通过例子来:
最后的10封邮件发送完毕我是想等所有子进程运行完毕再打印,但是从运行结果来看,这并没有达到我们的预期,因为父进程和子进程是异步的。
聪明的小明问了:那我在最后的print语句之前让程序休眠不就好了?
非常聪明,但是治标不治本,这样做只是让程序陷入了休眠状态,但是并没有从根本上解决异步的问题,它们还是异步,只是异步到了休眠。
这时我们可以用上join()方法:
得到的运行结果:
原理:
join()方法表示为给进程添加阻塞,也就是进程运行到这里就会停滞。再没有用上join方法之前,for循环会同时创建这10个进程,但是用上了join方法之后,必须依次执行循环,因为第一次创建进程到了join()就会阻塞,直到第一次进程完成,join方法才会释放阻塞,开始第二次循环,如此往复执行十次。
但是:
从根本上上来讲,join方法帮我们把异步变成了同步,虽然可以更加有序,但是并没有给我增加效率,异步的同时执行还是我们需要的,因为可以节省时间。而join方法将异步编程同步之后,反而拖累了工作效率。
当然,也有解决的办法:
将进程全部添加到一个列表中,进程启动的时候仍然是异步,只有结束时所有的阻塞都解除了,主程序才能执行。
守护进程
守护进程(daemon)是一类在后台运行的特殊进程,是一个在后台运行并且不受任何终端控制的进程。用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。守护进程最重要的特性是后台运行。
换言之,守护进程会随着主进程代码的执行完毕而结束。
我们再看一段:
效果也是一样的,只是多了一个func2,这里只有func1是守护进程。所以守护进程在主进程代码执行完毕时就结束了,而func2不是守护进程,所以可以继续运行。
可能有小明会很疑惑,守护进程到底有什么用?
守护进程其实可以作为程序的报活,每隔一段时间向一台机器汇报自己的状态,死了就不汇报了。(先这样理解吧)
进程锁-LOCK
Lock锁,什么叫Lock锁,我们还是通过一个直观的例子来。
我们建一个json文件,来模拟抢票,是的,就是抢票:
建一个json文件
{'count':2} #表示余量为2
实现抢票
明明只有两张票,却都抢到了。。。。
但我们仔细看,其实json文件中只修改了一次数据。因为这是一个异步程序,五个用户同时打开并且读取了json文件的内容,也就是说数据的修改是在外部的,而不是在json文件内,只要同时打开并读取,那么一开始五个用户读取到的内容都是一样的{'count':2},五个用户又都在外面对数据进行修改,修改完了再保存回去,也就是五个人保存的数据都是{'count':1},发生了覆盖现象,当涉及数据的修改时,异步其实很不安全。
所以我们可以采用加锁(互斥锁,这里是进程的互斥锁,线程也有锁)的方法。互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即上锁( lock )和解锁( unlock )。原理为:
没有上锁的时候,用户可以一起涌入数据文件,对数据文件内的信息进行修改。但是当上锁之后,访问数据文件就只有一个通道了,虽然大家都是同时发起访问的,但是进入数据文件的的用户只能有一个,然后等这个用户修改完了退出文件之后,通道才会开放给其他用户。程序还是异步的,只是在数据修改环节限制了流量。
这就使得异步的程序达到了同步的效果。
信号量-Semaphore
互斥锁(Lock)同时只允许一个进程修改数据,而信号量(Semaphore)则允许多个人同时修改数据。互斥锁就相当于你家的卫生间,只有一个坑位,同时只能一个人上厕所;而信号量则相当于公共厕所,有多个坑位,可以多个人同时上厕所。比如现在有10个人需要上厕所,现在公共厕所只有3个坑位,这时候就先有3个人上厕所,等其中一个或者多个人出来之后,另外的人才能进去。
Semaphore管理一个内置的计数器,每当调用acquire()时内置计数器-1;调用release() 时内置计数器+1;计数器不能小于0;当计数器为0时,acquire()将阻塞进程直到其他进程调用release()
事件-Event
再来一个红灯停绿灯行:
审核编辑:刘清
-
计数器
+关注
关注
32文章
2255浏览量
94470 -
Lock
+关注
关注
0文章
10浏览量
7767 -
进程
+关注
关注
0文章
203浏览量
13959 -
信号量
+关注
关注
0文章
53浏览量
8330
发布评论请先 登录
相关推荐
评论