python-多进程编程(一)

进程和线程

进程的定义

进程的定义有很多,普遍的定义是进程是一个程序在一个数据集上动态执行的过程。

进程一般由程序,数据集和进程控制三部分组成。

程序是指各种指令的集合,表述这我们需要计算机需要执行的动作。

数据集则是在程序执行的过程中用到的数据和一些资源

至于进程控制则是用于cpu对进程进行切换的一些标志位

线程的定义

线程可以理解成进程的进程,用于一个进程之间的多任务切换。而一个进程起码拥有一个线程,线程是进程执行的实体。

进程和线程之间的区别

  • 进程和进程之间的资源是不共享的,内存是互相隔离的,保障程序之间的安全性;而线程之间之间的内存是共享的,用于提高程序的运行效率。
  • 进程具有一定独立功能的程序关于某个数据集合上一次运行活动,是拥有资源的;线程是进程的一个实体,是CPU调度和分派的的基本单位,它是没有拥有资源的。

线程简单入门

基础

在这个例子中,主线程main产生两个子线程t1和t2,这两个子线程若串行则需要运行六秒,从打印结果可以看出,使用线程并行后只需要运行3秒。而“end”是主线程运行的内容。

import threading
import time


def myfunc(name):
    print("%s begin run %s"%(name,time.ctime()))
    time.sleep(3)
    print("%s stop run %s" %(name,time.ctime()))


if __name__ == "__main__":
    t1 = threading.Thread(target=myfunc,args=("hyj",))
    t2 = threading.Thread(target=myfunc, args=("zuxian",))

    t1.start()
    t2.start()

    print("end")
    
#########################
hyj begin run Thu Jan 16 16:40:44 2020
zuxian begin run Thu Jan 16 16:40:44 2020
end
zuxian stop run Thu Jan 16 16:40:47 2020
hyj stop run Thu Jan 16 16:40:47 2020

join方法

join方法是指使用了该方法的线程若没有运行完毕之前,主线程会一直阻塞不会往下运行。
我们在以下例子中来看一下运行结果,end就会在t1和t2线程都执行完毕后再进行打印。

import threading
import time


def myfunc(name):
    print("%s begin run %s"%(name,time.ctime()))
    time.sleep(3)
    print("%s stop run %s" %(name,time.ctime()))


if __name__ == "__main__":
    t1 = threading.Thread(target=myfunc,args=("hyj",))
    t2 = threading.Thread(target=myfunc, args=("zuxian",))

    t1.start()
    t2.start()
    #join方法要在启动线程的代码的后面
    t1.join()
    t2.join()

    print("end")
###################
hyj begin run Thu Jan 16 16:47:04 2020
zuxian begin run Thu Jan 16 16:47:04 2020
zuxian stop run Thu Jan 16 16:47:07 2020
hyj stop run Thu Jan 16 16:47:07 2020
end

守护线程setDaemon

在正常情况下,主进程会等待子进程执行完毕后才退出,这样有时候主进程的代码在执行完毕后,子进程仍然会执行代码。而setDaemon方法会后子进程会随着主进程的结束后就进行退出

import threading
import time


def myfunc(name):
    print("%s begin run %s"%(name,time.ctime()))
    time.sleep(3)
    print("%s stop run %s" %(name,time.ctime()))


if __name__ == "__main__":
    t1 = threading.Thread(target=myfunc,args=("hyj",))
    t2 = threading.Thread(target=myfunc, args=("zuxian",))
    #守护线程要在线程启动之前
    t1.setDaemon(True)
    t1.start()
    t2.start()

###################
hyj begin run Thu Jan 16 17:10:59 2020
zuxian begin run Thu Jan 16 17:10:59 2020
end
zuxian stop run Thu Jan 16 17:11:02 2020

threading的其余一些方法

  • run():用于表示线程活动的方法
  • start():启动线程活动
  • isAlive():返回线程是否活动
  • getName():返回线程名
  • setName():设置线程名
  • threading.currentThread():返回当前的线程变量
  • threading.enumerate():返回一个包含正在运行的线程list。正在运行只线程启动后、结束前,不包括启动前和终止后。
  • threading.activeCount():返回正在运行的线程数量

进程简单基础入门

多进程的使用方法和多线程的使用方法类似,主要是模块不同,采用的是multiprocessing这个模块,也有setDaemon和join方法

from multiprocessing import Process
from time import sleep

def func1():
    sleep(0.5)
    print("我还活着")

if __name__ == '__main__' #注意一定要在主进程下运行
    while True:
        p = Process(target=func1)
        p.start()
        print("main process")

使用面向的对象方法启动进程

通过改写Process里面的run方法,来改变子进程运行的代码

from multiprocessing import Process
from time import sleep
import os

class Myproccess(Process):
    def run(self):
        print("我是一个子进程,进程号是%i"%os.getpid())


if __name__ == '__main__':
    print("我是一个主进程,进程号是%i"%os.getpid())
    for i in range(2):
        p = Myproccess()
        p.start()
#######
我是一个主进程,进程号是39552
我是一个子进程,进程号是39553
我是一个子进程,进程号是39554

进程之间的数据隔离

由于进程是在内存地址新开辟的一段物理空间,所以属于进程之间的数据是无法互相改写的,这是和线程不同的地方

from multiprocessing import Process
from time import sleep
import os

class Myproccess(Process):
    def run(self):
        global i
        i = 3
        print("我是一个子进程,进程号是%i"%os.getpid())
        print(i)


if __name__ == '__main__':
    print("我是一个主进程,进程号是%i"%os.getpid())
    i = 100
    print(i)
    for i in range(1):
        p = Myproccess()
        p.start()
-------------------------
我是一个主进程,进程号是39622
100
我是一个子进程,进程号是39623
3

可见每一个进程的全局变量都是不同的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值