多进程编程2 参考资料:《python开发技术详解》

==========python开发技术详解

os.system起的子进程会结束后将控制权返回python;
os.exec会接管python进程,不会将控制权返回python,如在python里调用exec将记事本打开,则原来的python解释器就会退出。

exit 可以温和的方式退出进程;
abort会以暴力方式退出进程
///////////////////
subprocess作为进程管理的高级模块,提供了一个类和两个函数来管理进程。
subprocess.popen中的shell:当shell为false时,popen将调用os.execvp执行对应的程序。但shell为true时,若命令为字符串,popen直接调用系统shell来执行指定的程序。

若命令为一个序列,则第一项是命令字符串,其他项是命令的附加参数。

若需要等待子进程的结束,可以使用popen类的wait()函数
若需要管理子进程的输入和输出,可以改变popen类的stdin、stdout和stderr

在输出结果后,stdout成为一个可读的输出对象

  因为数据是缓存在内存里,所以当数据量很大时,不要用communicate

 subprocess的call和check_all是对popen的一种简化,call可以直接生成子进程,并等待子进程结束。check_all和call的区别是,若返回值不为0则触发异常CallProcessError,异常对象的returncode属性中有返回值

 

信号是操作系统的一种软中断当同时使用信号和线程时,总是在主线程中执行signal函数,所以不能使用信号作为线程间的通信方式。
signal模块不是用python实现的,是直接依赖于具体系统平台的,所以signal模块仅仅包含系统中定义的信号。

signal。signal()函数的作用是未中断信号注册指定的信号处理函数

signal模块有两个预设的信号处理函数:SIG_DFL和SIG_IGN 【默认处理函数和忽略信号】
自定义的处理函数要包含两个参数:信号编号和当前的堆栈帧:def signal_handler(signum,fram):

signal模块提供了查询特定信号处理函数的方法:getsignal,返回值是可调用的python对象、或SIG_IGN、SIG_DFL、None

当程序在执行IO操作时收到信号中断,可能使得在信号处理函数执行完毕后触发异常,或直接触发异常

当同时使用信号和线程时,总是在主线程中执行signal函数,所以不能使用信号作为线程间的通信方式。

=========多线程

Queue是多线程安全的,常用于线程间通信,其构造函数可以指定一个maxsize,若maxsize小于0或等于0,则表示队列的长度么有限制;当大于0时则指定了队列的长度;

Queue最重要的方法是put和get,其他方法由于多线程的原因,返回值不一定是准确的,如qsize、empty

对于一个线程,start方法最多只能调用一次,join方法可以被调用多次;

为了让主线程等待子线程,需要在主线程中调用子线程的join方法;线程不能在自己的运行代码中调用join,否则会造成死锁

join方法可以接收一个time参数作为超时时间

 线程中的局部变量:treading.local,其成员变量在每个线程中都是不同的

======同步

4种线程同步机制:锁;条件变量;信号量;同步队列

条件变量condition:除了有acquire、release,还有wait、nofity、notifyAll
notifyAll与notify的区别:notifyall可以唤醒所有等待此条件的线程
wait方法或nofity方法的调用都是在获取了互斥锁的前提下进行的

=====从下图看,条件变量的acquire、release也是成对出现的。在全局创建一个条件变量,然后传给生产者和消费者

 

信号量Semaphore:主要用在对“有限”资源进行同步,在构造信号量对象时,指定资源个数,如:Semaphore(5)
信号量也有acquire和release,当执行acquire时,若内部计数器大于0,则减1,程序继续向下执行,若内部计数等于0,则阻塞当前线程,直到其他线程使用release方法。release方法使计数器加1,同时唤醒等待的线程

 

 

 

posted on 2020-04-22 21:42  我和你并没有不同  阅读(177)  评论(0编辑  收藏  举报