python入门20进程 线程

1.现代操作系统:
OS X,UNIX,Linux,Windows 等都是支持“多任务”的操作系统

单核CPU:通过操作系统轮流让各个任务交替执行,从CPU的视角看,每个任务都是交替执行的,由于CPU的执行速度非常快,我们感觉就像所有任务都在同时执行一样。

多核CPU:由于任务数量远远多于CPU的核心数量,操作系统会自动把很多任务轮流调度到每个核心上执行。

**并发:**看上去一起执行,任务数多于CPU核心数
**并行:**真正一起执行,任务数小于等于CPU核心数
实现多任务的方式:1.多线程模式 2.多进程模式 3.协程模式 4.多进程+多线程

一个正在执行的任务就是一个进程,比如打开一个浏览器就是启动一个浏览器进程(程序执行和资源分配的基本单位,数据段,代码段和堆栈段)
关于进程线程介绍比较详细的网站:https://zhuanlan.zhihu.com/p/46368084

2.启动进程实现多任务:

from multiprocessing import Process
def func(str):
    while True:
        print("hi hi %s"%(str))
        time.sleep(1.2)
    
if __name__=="__main__":
    print("主进程启动")
    #创建子进程
    #target说明进程执行的任务
    p = Process(target=func,args=(" ",)
    #启动进程
    p.start()
    while True:
        print("hello hellio")
        time.sleep(1)
#os.getpid()获取当前进程的ID号
#os.getppid()获取当前进程的父进程的id号

3.父子进程的先后顺序

from multiprocessing import Process
def func():
    print("子进程启动")
    time.sleep(3)
    print("子进程结束")
if __name__=="__main__":
    print("父进程启动")
    p=Process(target=func)
    p.strat()
    print("父进程结束")

程序执行结果:父进程启动
             父进程结束
             子进程启动
             子进程结束

#父进程的结束不能影响子进程,让父进程等子进程结束再执行父进程:
p.join()
       

4.全局变量在多个进程中不能共享

num = 100
def func():
    print("子进程开始")
    global num
    num+=1
    print(num)
    print("子进程结束")
if __name__="__main__":
    print("父进程开始")
    p=Process(target=func)
    p.start()
    p.join()
    print(num)
    print("父进程结束")
    #在创建子进程时对全局变量做了备份,父进程与子进程中的num是两个完全不同的变量

5.启动大量子进程

def func(name):
    print("子进程%d启动--%s"%(name,os.getpid() ))
    start = time.time()
    time.sleep(random.choice([1,2,3]))
    end = time.time()
    print("子进程%d结束--%s--耗时%.2f")%(name,os.getpid(),end-start)

if __name__ =="__main__":
    print("父进程启动")
    #创建多个进程,进程池
    #pool默认大小是cpu核心数
    p=Pool(2)
    for i in rang(3):
        #创建进程,放入进程池
        p.apply_async(run,args=(i,))
    #调用join前必须先调用close,调用close后不能再继续添加新的进程
    p.close()
    p.join()
    
    print("父进程结束")
    

    

6.实现文件拷贝

import os 
from multiprocessing import  Pool
#复制文件的方法
def copyFile(rPath,wPath):
    fr = open(rpath,"rb")
    fw = open(wpath,"wb")
    context = fr.read()
    fw.write(context)
    fr.close()
    fw.close()

path="  "
topath="  "
#读取路径下的所有文件
fileList = os.listdir(path)
#启动for循环处理每一个文件
start = time.time()
for fileName in fileList:
    copyFile(os.path.join(path,fileName),os.path.join(topath.fileName))
end = time.time()
print("总耗时%0.2f"%(end-start))

用进程方式实现文件拷贝

if __name__=="__main__":
    # 读取path下的所有文件
    fileList = os.listdir(path)
    start = time.time()
    pp=Pool(2)
    for fileName in fileList:
        pp.apply_async(copyFile, args=(os.path.join(path,filename),os.path.join
(toPath,filename) ))
    pp.close()
    pp.join()
    end = time.time()

#分装进程对象

from multiprocessing import Process
class SunckProcess(Process):
    def __init__(self, name):
        Process.__init__(self)
        self.name = name
    def run(self):
        print("")
        time.sleep(3)
        print("")
from sunckProces import SunckProcess
if __name__ == "__main__":
    p = SunckProcess("test")
    #自动调用p进程对象的run方法
    p.start()
    p.join()
    print("父进程结束")

7.进程间的通信

write           read
A B C         
from multiprocessing import Process, Queue
def write(q):
    print("启动写子进程%d"%(os.getpid()))
    for chr in ["A","B","C","D"]:
        q.put(chr)
        time.sleep(1)
    print("结束写子进程%d"%(os.getpid()))
def read():
    print("启动读子进程%d"%(os.getpid()))
    while True:
        value = q.get(True)
        print("value="+value)
    print("结束读子进程%d"%(os.getpid()))    

if __name__="__main__":
    #父进程创建队列,并传递给子进程
    q=Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    pw.start()
    pr.start()
    pw.join()
    #强制结束
    pr.terminate()
    print("父进程结束")

8.线程
#一个进程内部 同时干多件事,需要同时运行多个“子任务”,这些子任务叫做线程

线程管理主要通过threading模块。
threading模块提供的类:Thread, Lock, Rlock, Condition, Semaphore, Event, Timer, local。
常用方法:
threading.currentThread() 返回当前的线程变量
threading.enumerate() 返回一个包含正在运行的线程的list
threading.activeCount():返回正在运行的线程数量
模块常量:
threading.TIMEOUT_MAX设置threading全局超时时间。

Thread类属性: name:线程名 ident:线程的标识符 daemon:布尔值,表示这个线程是否是守护线程
Thread类方法:init(group=None, target=None, name=None, args=(),kwargs={}, verbose=None, daemon=None)
实例化一个线程对象,需要一个可调用的target对象,以及参数args或者kwargs。还可以传递name和group参数。
start():开始执行该线程
run():定义线程的方法
join(timeout=None) 直至启动的线程终止之前一直挂起;

启动线程

import threading,time
def run():
    print("子线程(%s)开始"%(threading.current_thread().name))
    #实现线程的功能
    print("打印")
    time.sleep(2)
    print("子线程(%s)开始"%(threading.current_thread().name))
if __name__=="__main__":
    #任何进程默认会启动一个线程,称为主线程,主线程可以启动新的子线程
    print("主线程(%s)启动"%(threading.current_thread().name))
    #创建子线程
    t = threading.Thread(target=run, name="runThread")
    t.start()
    #等待线程结束
    t.join()
    print("主线程(%s)结束"%(threading.current_thread().name))

多线程和多进程最大的不同在于,多进程中 同一个变量各自有一份拷贝存在每个进程中互不影响。 多线程中,所有变量由线程共享,任何一个变量可以被任意一个线程修改。

num=10
def run(n):
    global num
    for i in range(10000):
        num = num+n
        num = num-n
if __name__=="__main__":
    t1 = threading.Thread(target=run,args=(6,)) 
    t2 = threading.Thread(target=run,args=(9,)) 
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("num=",num)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值