引入进程和线程的概念及区别

threading模块提供的类:  
  Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。

1.什么是进程

计算机程序只不过是磁盘中可执行的二进制(或其他类型)的数据。它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期。

进程(有时被称为重量级进程)是程序的一次执行。每个进程都有自己的地址空间、内存、数据栈及其它记录其运行轨迹的辅助数据。

操作系统管理在其上运行的所有进程,并为这些进程公平的分配时间,进程也可以通过fork和spawn操作来完成其它的任务。

不过各个进程有自己的内存空间、数据栈等,所以只能使用进程间通讯,而不能直接共享信息

2.线程的基本概念

线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。

 

3、线程和进程的关系以及区别?

** 进程和线程的关系:**

  • (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

  • (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

  • (3)处理机分给线程,即真正在处理机上运行的是线程

  • (4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体.

进程与线程的区别:

  • (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

  • (2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行

  • (3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.

  • (4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

1 多进程创建方式

可以归纳为三种:fork,multiprocessing以及进程池Pool。

(1) fork方式

1 import os
2 
3 # 注意,fork函数,只在Unix/Linux/Mac上运行,windows不可以
4 pid = os.fork()
5 
6 if pid == 0:
7     print('哈哈1')
8 else:
9     print('哈哈2')

注意:fork()函数只能在Unix/Linux/Mac上面运行,不可以在Windows上面运行。

说明:

  • 程序执行到os.fork()时,操作系统会创建一个新的进程(子进程),然后复制父进程的所有信息到子进程中
  • 然后父进程和子进程都会从fork()函数中得到一个返回值,在子进程中这个值一定是0,而父进程中是子进程的 id号

在Unix/Linux操作系统中,提供了一个fork()系统函数,它非常特殊。

普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。

子进程永远返回0,而父进程返回子进程的ID。

这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。我们可以通过os.getpid()获取当前进程ID,通过os.getppid()获取父进程ID。

那么,父子进程之间的执行有顺序吗?

答案是没有!这完全取决于操作系统的调度算法。

而多次fork()就会产生一个树的结构:

Python中的线程和进程

(2)multiprocessing方式

如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。由于Windows没有fork调用,难道在Windows上无法用Python编写多进程的程序?当然可以!由于Python是跨平台的,自然也应该提供一个跨平台的多进程支持。multiprocessing模块就是跨平台版本的多进程模块。

 1 import  os
 2 import time
 3 
 4 from multiprocessing import  Process
 5 
 6 def run_proc(name):
 7     print('子进程运行中,name%s,pin=%d...'%(name,os.getpid()))
 8 
 9     time.sleep(10)
10     print('子进程已经结束')
11 
12 if __name__=='__main__':
13     print('父进程%d.'%os.getpid())
14     p=Process(target=run_proc,args=('test',))
15     print('子进程将要执行')
16     p.start()

Python中的线程和进程

从结果我们看出,只要通过start()开启了子进程之后,主进程会等待子进程执行完才结束!

Process的语法结构如下:

import  os
import time
from multiprocessing import Process
class MyProcess(Process):
    def __init__(self,name):
        Process.__init__(self)
        self.name=name

    def run(self):
        print('子进程运行中,name= %s ,pid=%d...' % (self.name, os.getpid()))
        import time
        time.sleep(10)
        print('子进程已结束')
        

if __name__=="__main__":
    my=MyProcess('test')
    my.start()

(3)Pool方式

#coding=utf-8
from multiprocessing import Pool
import os, time, random

def worker(msg):
    print("%s开始执行,进程号为%d"%(msg, os.getpid()))
    time.sleep(1)
    print "%s执行完毕"%(msg)

if __name__ == '__main__':
    po = Pool(3)  # 定义一个进程池,最大进程数3
    for i in range(10):
        # Pool.apply_async(要调用的目标,(传递给目标的参数元祖,))
        # 每次循环将会用空闲出来的子进程去调用目标
        po.apply_async(worker, (i,))

    print("----start----")
    po.close()  # 关闭进程池,关闭后po不再接收新的请求
    po.join()  # 等待po中所有子进程执行完成,必须放在close语句之后
    print("-----end-----")

实现一个多进程下的文件夹复制功能:

 1 #coding=utf-8
 2 
 3 import os
 4 from multiprocessing import Pool
 5 
 6 
 7 def copyFileTask(name, oldFolderName, newFolderName):
 8     # 完成copy一个文件的功能
 9     fr = open(oldFolderName+"/"+name, 'rb+')
10     fw = open(newFolderName+"/"+name, 'wb+')
11 
12     str = fr.read(1024 * 5)
13     while (str != ''):
14         fw.write(str)
15         str = fr.read(1024 * 5)
16 
17     fr.close()
18     fw.close()
19 
20 
21 def main():
22     # 获取要copy的文件夹名字
23     oldFolderName = raw_input('请输入文件夹名字:')
24     # 创建一个文件夹
25     newFolderName = oldFolderName+'-复件'.decode('utf-8').encode('gbk')
26     os.mkdir(newFolderName)
27 
28     #获取old文件夹里面所有文件的名字
29     fileNames = os.listdir(oldFolderName)
30 
31     #使用多进程的方式copy原文件夹所有内容到新的文件夹中
32     pool = Pool(5)
33     for name in fileNames:
34         pool.apply_async(copyFileTask, (name, oldFolderName, newFolderName))
35 
36     pool.close()
37     pool.join()
38 
39 if __name__ == '__main__':
40     main()
View Code

相关文章:

  • 2021-06-15
  • 2021-06-22
  • 2021-10-12
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-16
猜你喜欢
  • 2022-02-05
  • 2022-03-01
  • 2021-11-04
  • 2021-10-24
  • 2022-12-23
  • 2021-07-03
  • 2021-10-25
相关资源
相似解决方案