Python学习-多线程和多进程

基本概念

  1. 进程:程序的一次执行
  2. 线程:CPU的基本调度单位

线程

线程的创建

线程的创建主要通过threading模块

print('主线程开始')

from threading import Thread
import threading
from time import sleep

def sub_fun(arg1,arg2):
    print('子线程开始')
    print('子线程函数参数时:{0},{1}'.format(arg1,arg2))
    sleep(5)
    print('子进程结束')

thread = Thread(target=sub_fun, args=('参数1','参数2'))

thread.start()

thread.join()

print('主线程结束')

线程共享全局变量和锁

在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据
缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)

from threading import Thread
import time

num = 0 

def add1(n):
    global num
    for i in range(n):
        num = num+1
    print('in add1, num is {0}\n'.format(num))
    
def add2(n):
    global num
    for i in range(n):
        num = num+1
    print('in add2, num is {0}\n'.format(num))   

thread1 = Thread(target=add1, args=(1000000,))
thread1.start()

thread2 = Thread(target=add2, args=(1000000,))
thread2.start()

time.sleep(5)
print('final num is {0}\n'.format(num))

最后运行的结果是

in add2, num is 1295511
in add1, num is 1324484
final num is 1324484

对num加1,2000000次,结果却不是2000000,这是由于线程共享全局变量

在num=0时,thread1 thread2同时取得num=0。
此时thread1 sleeping,thread2 running, thread2使num=1
然后thread2 sleeping,thread1 running, thread1使num=1
这就导致两个线程重复操作了两次,num结果仍是1

简单来说就是线程被覆盖了,这时可以使用 threading库里面的锁对象 Lock 去保护

lock = threading.Lock()

lock.acquire()
lock.release()

进程

进程的创建

在python中进程的创建主要通过Process函数
Process([group [, target [, name [, args [, kwargs]]]]])

  1. target:如果传递了函数的引用,可以任务这个子进程就执行这里的代码
  2. args:给target指定的函数传递的参数,以元组的方式传递
  3. kwargs:给target指定的函数传递命名参数
  4. name:给进程设定一个名字,可以不设定
  5. group:指定进程组,大多数情况下用不到

Process创建的实例对象的常用方法:

  1. start():启动子进程实例(创建子进程)
  2. is_alive():判断进程子进程是否还在活着
  3. join([timeout]):是否等待子进程执行结束,或等待多少秒
  4. terminate():不管任务是否完成,立即终止子进程

Process创建的实例对象的常用属性:

  1. name:当前进程的别名,默认为Process-N,N为从1开始递增的整
  2. pid:当前进程的pid(进程号)
from multiprocessing import Process
import os
import time

def sub_fun():
        print('子进程运行中,pid=%d...' % os.getpid())

if __name__ == '__main__':
    print('父进程pid: %d' % os.getpid())
    for i in range(3):
        p = Process(target=sub_fun)
        p.start()

进程间的通信

进程间有多种通信机制,下面就常用的Queue为例进行说明

from multiprocessing import Process,Queue
import os,time,random

def write(q):
    for value in ['a','b','c']:
        print('put {0} to queue'.format(value))
        q.put(value)
        time.sleep(random.random())

def read(q):
    while not q.empty():#此处死循环,ctrl+c终止
        value = q.get(True)
        print('get {0} to queue'.format(value))
        q.put(value)
        time.sleep(random.random())

if __name__ == '__main__':
    q = Queue()

    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))

    pw.start()
    pw.join()

    pr.start()
    pr.join()

    print('-----ok------')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值