- 进程就是 *** 作系统中执行的一个程序, *** 作系统以进程为单位分配存储空间,每一个进程都有自己的地址空间、数据栈以及其他用于跟踪进程执行的辅助数据。
*** 作系统管理所有进程的执行,为进程合理分配资源。
进程可以通过fork或spawn的方式来创建新的进程来执行其他的任务,不过新的进程也有自己独立的内存空间,因此必须通过进程间通信机制(IPC,Inter-Process Communication)来实现数据共享,具体的方式包括管道、信号、套接字、共享内存区等。
- 线程就是一个进程中多个并发的执行线索,拥有多个可以获得CPU调度的执行单元。
线程相比于进程,因为线程在同一个进程下,他们之间共享上下文,所以线程间的信息共享和通信更加容易。
在单核的cpu种并发是不能真正的实现,在具体的时刻能够获得CPU的只有唯一的一个线程,他们是时间共享CPU。
通过任务管理器就可以看到进程。
Python支持多进程又支持多线程,因此使用Python实现并发编程主要有3种方式:多进程、多线程、多进程+多线程
Unix和Linux *** 作系统上提供了fork()系统调用来创建进程,调用fork()函数的是父进程,创建出的是子进程,子进程是父进程的一个拷贝,但是子进程拥有自己的PID。
fork()函数非常特殊它会返回两次,父进程中可以通过fork()函数的返回值得到子进程的PID,而子进程中的返回值永远都是0。
Python的os模块提供了fork()函数。
由于Windows系统没有fork()调用,因此要实现跨平台的多进程编程,可以使用multiprocessing模块的Process类来创建子进程,而且该模块还提供了更高级的封装,例如批量启动进程的进程池(Pool)、用于进程间通信的队列(Queue)和管道(Pipe)等。
举个例子:
这个例子运行时时一个一个方法执行,我们用多进程的方法来使用。
from multiprocessing import Process
from os import getpid
from random import randint
from time import time, sleep
def download_task(filename):
print('启动下载,进程号[%d].' % getpid())
print('开始下载%s...' % filename)
time_download = randint(5, 10)
sleep(time_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_download))
def main():
start = time()
p1 = Process(target=download_task, args=('如何勾搭九亿少女.pdf', )) ##进程一 target传入一个该进程要执行的函数 args是元组,给函数传递参数
p1.start() ###开始进程1
p2 = Process(target=download_task, args=('如何迷倒少男.txt', )) ##进程二
p2.start() ##开始进程2
p1.join() #join 等待进程结束
p2.join()
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
用多线程的方法可以观察到现象是两个任务一起开始,时间是两个任务中用时最长的一个。
还可以用subprocess模块中的类和函数来创建和启动子进程,这个自行学习。
多线程开发使用threading模块,该模块的多线程编程提供了更好的面向对象的封装。
再将上面进程的例子实现一次。
from random import randint
from threading import Thread
from time import time,sleep
def download(filename):
print('开始下载%s。
'
% filename)
time_download=randint(5,10)
sleep(time_download)
print('%s 完成下载 耗时%d '%(filename,time_download))
def main():
start =time()
t1=Thread(target=download,args=('如何迷倒九亿少女.pdf'))
t1.start()
t2 = Thread(target=download, args=('如何勾搭少男.txt'))
t2.start()
t1.join()
t2.join()
end=time()
print('种耗时%s'% (end-start))
if __name__=='__main__':
main()
线程还可以自定义哦,用继承的形式,自定义一个类,让它继承Thread类
from random import randint
from threading import Thread
from time import time, sleep
class Download(Thread): ##继承Thread类
def __init__(self,filename):
super().__init__()
self.filename=filename
def run(self):
print('开始下载%s' % self.filename')
time_download=randint(5,10)
sleep(time_download)
print('%s下载完成 耗费了%d秒’ %(self.filename,time_download)
def main():
start = time()
t1 = DownloadTask('Python从入门到住院.pdf')
t1.start()
t2 = DownloadTask('Peking Hot.avi')
t2.start()
t1.join()
t2.join()
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
线程可以共享进程空间,要实现对各线程间的通向简单一点,可用全局变量(资源)来共享给多线程。
但是这样有可能产生不可控的结果导致程序失效或崩溃,像这样的资源称为临界资源。
对临界资源的访问要加上保护,否则资源会处于“混乱”的状态。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)