多线程与多进程的理解

2018-03-18  本文已影响0人  xu一直在路上

首先来说说他两个的区别,进程是资源分配的最小单位,线程则是CPU调度的最小单位,多进程不能共享全局变量,当使用全局变量的时候势必会造成,race condition,而多线程则可以共享全局变量,对于大量需要CPU工作的时候,进程就显得大有优势,因为多线程需要CPU来不停切线程换大量时间都消耗在,切换线程上,而对于IO操作上(比如文件存储,网络爬虫),多线程就有巨大优势。
下面来一些简单的小例子:

进程:
from multiprocessing import Process

def run(num):
    print('this is process')
    for i in range(5):
        print(num,i)
if __name__ =='__main__':
    for i in  range(5):
        p = Process(target=run,args=(i,))#创建多个进程
        p.start()#启动
        p.join()
线程:
import threading
def run(num):
    print('hello everyone')
    for i in range(5):
        print('%s -- %d' % (threading.current_thread().name, i))#注意这里的'threading.current_thread().name'这个是获取当前正在运行的线程名字

if __name__ == '__main__':
    for i in  range(5):
        s = threading.Thread(target=run, args=(i,))#创建多个线程
        s.start()#启动线程

以上是最简单的多进程和多线程

当多个线程同时处理同样一个逻辑的时候,就会造成数据混乱如下:

import threading
num = 0#定义全局的变量
def func1(n):
    global num
    for i in range(100000):
        num = num - n
        num = num + n
if __name__ =='__main__':
    s =threading.Thread(target=func1,args=(6,))
    s1 =threading.Thread(target=func1,args=(9,))
    s.start()
    s1.start()
    s.join()
    s1.join()
    print(num)
打印结果为 -6,

正常情况下,应该为0为什么会变成-6呢?因为多线程是共享全局变量的,造成了多个线程运行时产生了数据混乱,为了解决这个问题,我们可以引入,线程锁的概念:

线程锁的应用:
import threading
lock = threading.Lock()#这里我们创建一个锁的实例
num =0
def func1(n):
    global num
    for i in range(100000):
        lock.acquire()#这里上锁
        try:#
            num = num-n
            num = num+n
        finally:
            lock.release()#释放锁

if __name__ =='__main__':
    s =threading.Thread(target=func1,args=(6,))
    s1 =threading.Thread(target=func1,args=(9,))
    s.start()
    s1.start()
    s.join()
    s1.join()
    print(num)
打印结果为 0

锁是怎么工作的呢?其实当一个线程遇到lock.acquire()的时候会上锁,其他大的线程就会在此挂起,等线程遇到lock.release()就会把锁释放,被挂起的线程才会进入逻辑运算,避免了多个线程同时运算造成的结果混乱。为什么加 try---finally 呢?因为在大量计算中可能会出现不可预期的错误,从而导致线程锁一直被锁死,导致整个程序报废。

总结:对于计算密集型多进程优势,对于io密集型多线程有优势。注意线程锁的应用。

上一篇 下一篇

猜你喜欢

热点阅读