进程与线程的一些知识

介绍进程、线程的概念、多进程和多线程的区别、python中对多进程和多线程的不同的实现方式。

一、进程

进程简单地说是一个程序在计算机系统中执行的一个过程,是操作系统资源分配的基本单位,从更深的层面讲,是操作系统的一种抽象。如你在电脑上运行了QQ这个软件,这就是一个进程。


二、线程

然而,一个程序中往往不止一个逻辑单元,而是存在多个不同导向的代码模块。如,你可以运行QQ一边给一个人传文件一边和另外一个人聊天,聊天和传文件就是一个进程中执行不同功能(也就是不同导向的逻辑单元)模块,这就是线程。也就是说,线程是比进程更小的单位,它们是CPU能够调度的基本单位,同一个进程内部,所有线程共享资源。


三、多进程和多线程的区别

这里只说最重要的两个区别:1、多进程每个进程都要分配相应的资源,而同一个进程的多个线程资源是共享的;2、进程之间的通信需要借助中介,而同一进程的线程之间可以直接通信。


四、python对于多进程的实现

1、基本实现方式

实现方式主要是利用multiprocessing模块(os模块的fork方法也可以,但那只在unix/linux环境下有效,且是复制父进程,应用面太窄)。对于少量的进程,可以对模块中的Process类传入想要运行的方法及方法的参数,然后调运该对象的start方法即可。对于较多的进程,可以创建进程池,即先实例化一个Pool对象,然后调用该对象的apply_async方法,该方法的参数同样是想要执行的方法和该方法的参数。

使用Process类

import os
from multiprocessing import Process
def run_proc(name):
    print 'Child process %s (%s) Running...' % (name, os.getpid())
if __name__ == '__main__':
    print 'Parent process %s.' % os.getpid()
    p_list=[]
    for i in range(5):
        p = Process(target=run_proc, args=(str(i),))
        p_list.append(p)
        print 'Process will start.'
        p_list[i].start()
    for p in p_list:
        p.join()
    print 'Process end.'

使用Pool类

from multiprocessing import Pool
import os, time, random

def run_task(name):
    print 'Task %s (pid = %s) is running...' % (name, os.getpid())
    time.sleep(random.random() * 3)
    print 'Task %s end.' % name

if __name__=='__main__':
    print 'Current process %s.' % os.getpid()
    p = Pool(processes=3)
    for i in range(5):
        p.apply_async(run_task, args=(i,))
    print 'Waiting for all subprocesses done...'
    p.close()
    p.join()
    print 'All subprocesses done.'

2、进程间的通信

进程间的同信必须借助媒介,这里主要介绍Queue,同样是来自multiprocessing模块的Queue类,该类本质就是数据结构中的队列,可以由父进程实例化一个对象,传递给各个子进程,或者将其公布在网络上,由各个进程同步到进程内部,再进行读取。


五、python对于多线程的实现

1、实现方法与多进程类似,只是它这里是通过threading模块的Thread类。

2、多线程的锁

之前说过,一个进程内的多个线程是共享资源,有些数据只能允许单个线程修改,这里就要用到同步锁。简而言之,在进程类实例化一个threading.RLock()对象,在对数据修改前使用acquire方法获取资源,完成操作后,使用release方法释放资源。

同步锁例子

import threading
mylock = threading.RLock()
num=0
class myThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self,name=name)

    def run(self):
        global num
        while True:
            mylock.acquire()
            print '%s locked, Number: %d'%(threading.current_thread().name, num)
            if num>=4:
                mylock.release()
                print '%s released, Number: %d'%(threading.current_thread().name, num)
                break
            num+=1
            print '%s released, Number: %d'%(threading.current_thread().name, num)
            mylock.release()


if __name__== '__main__':
    thread1 = myThread('Thread_1')
    thread2 = myThread('Thread_2')
    thread1.start()
    thread2.start()


Tips1:全局解释器锁(GIL)

python同一个进程内的多个线程无法使用多个CPU,一个进程只能一个核,无论该进程有多少线程,这是语言解释器层面的约束,无法通过第三方库来解决。所以对于计算密集型的程序要使用多进程,而对于网络IO 密集型的操作可以使用多线程。


Tips2:join方法

无论是多线程还是多进程,我们都用到了一个方法join,该方法的作用是进/线程同步。当进/线程执行该方法时,会阻塞其他进/线程,当自身执行完之后才允许其他进/线程执行。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值