多线程,多进程

程序是计算机上存储的可执行文件,当它运行起来就会加载到内存;

所以进程可以认为是程序的一次执行,或加载到内存中的一系列指令。进程的内部可以由一到多个线程构成。

windows系统不支持多进程。

forking工作原理

• fork(分岔)在Linux系统中使用非常广泛

• 当某一命令执行时,父进程(当前进程)fork出一个子进程

• 父进程将自身资源拷贝一份,命令在子进程中运行时,就具有和父进程完全一样的运行环境

进程的生命周期

• 父进程fork出子进程并挂起

• 子进程运行完毕后,释放大部分资源并通知父进程,

这个时候,子进程被称作僵尸进程

• 父进程获知子进程结束,子进程所有资源释放

多进程编程的思路

  1.  想清楚父子进程分别负责哪些工作
  2. 一 般来说,父进程只管生成子进程
  3. 子进程负责做具体的工作
  4. 一 定要注意,子进程做完它的工作之后,要彻底结束。

僵尸进程

• 僵尸进程没有任何可执行代码,也不能被调度

• 如果系统中存在过多的僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程

• 对于系统管理员来说,可以试图杀死其父进程或重启系统来消除僵尸进程

firking编程

• 需要使用os模块

• os.fork()函数实现forking功能

• python中,绝大多数的函数只返回一次,os.fork将返回两次

• 对fork()的调用,针对父进程返回子进程的PID;对于子进程,返回PID0

解决zombie问题

• 父进程通过os.wait()来得到子进程是否终止的信息

• 在子进程终止和父进程调用wait()之间的这段时间,子进程被称为zombie(僵尸)进程

• 如果子进程还没有终止,父进程先退出了,那么子进程会持续工作。系统自动将子进程的父进程设置为

init进程,init将来负责清理僵尸进程

• python可以使用waitpid()来处理子进程

• waitpid()接受两个参数,第一个参数设置为-1,表示与wait()函数相同;第二参数如果设置为0表示挂起父进程,直到子程序退出,设置为1表示不挂起父进程

• waitpid()的返回值:如果子进程尚未结束则返回0,否则返回子进程的PID

import os, time

def reap():

result = os.waitpid(-1, 1)

print('Reaped child process %d' % result[0])

pid = os.fork()

if pid:

print 'In parent. Sleeping 15s...'

time.sleep(15)

reap()

time.sleep(5)

print('parent done')

else:

print 'In child. Sleeping 5s...'

time.sleep(5)

print('Child terminating.')

多线程编程

多线程的动机

• 在多线程(MT)编程出现之前,电脑程序的运行由一个执行序列组成,执行序列按顺序在主机的中央处理器(CPU)中运行

• 无论是任务本身要求顺序执行还是整个程序是由多个子任务组成,程序都是按这种方式执行的

• 即使子任务相互独立,互相无关(即,一个子任务的结果不影响其它子任务的结果)时也是这样

• 如果并行运行这些相互独立的子任务可以大幅度地提升整个任务的效率

多线程任务的工作特点

• 它们本质上就是异步的,需要有多个并发事务

• 各个事务的运行顺序可以是不确定的,随机的,不可预测的

• 这样的编程任务可以被分成多个执行流,每个流都有一个要完成的目标

• 根据应用的不同,这些子任务可能都要计算出一个中间结果,用于合并得到最后的结果

进程

• 计算机程序只不过是磁盘中可执行的、二进制(或其它类型)的数据

• 进程(有时被称为重量级进程)是程序的一次执行

• 每个进程都有自己的地址空间、内存以及其它记录其运行轨迹的辅助数据

• 操作系统管理在其上运行的所有进程,并为这些进程公平地分配时间

线程

• 线程(有时被称为轻量级进程)跟进程有些相似。不同的是,所有的线程运行在同一个进程中,共享相同的运行环境

• 一个进程中的各个线程之间共享同一片数据空间,所以线程之间可以比进程之间更方便地共享数据以及相互通讯

多线程相关模块

• thread和threading模块允许程序员创建和管理线程

• thread模块提供了基本的线程和锁的支持,而threading提供了更高级别、功能更强的线程管理功能

• 推荐使用更高级别的threading模块

传递函数给Thread类

• 多线程编程有多种方法,传递函数给threading模块的Thread类是介绍的第一种方法

• Thread对象使用start()方法开始线程的执行,使用join()方法挂起程序,直到线程结束

传递可调用类给Thread类

• 传递可调用类给Thread类是介绍的第二种方法

• 相对于一个或几个函数来说,由于类对象里可以使用类的强大的功能,可以保存更多的信息,这种方法更为灵活

发布了67 篇原创文章 · 获赞 13 · 访问量 4068

猜你喜欢

转载自blog.csdn.net/tongzhuo1220/article/details/102833345