Python-进程VS线程

2018-08-24  本文已影响0人  时光清浅_许你心安_

进程和线程

进程之间的通信: q = multiprocessing.Queue()
进程池之间的通信: q = multiprocessing.Manager().Queue()
线程之间的通信: q = queue.Queue()

功能

定义的不同

进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源

区别

优缺点

互斥锁

#创建锁
mutex = threading.Lock()
#锁定
mutex.acquire([blocking])
#释放
mutex.release()

多线程-非共享数据

对于多线程中全局变量和局部变量是否共享

#coding=utf-8
    import threading
    import time

    class MyThread(threading.Thread):
        # 重写 构造方法
        def __init__(self,num,sleepTime):
            threading.Thread.__init__(self)
            self.num = num
            self.sleepTime = sleepTime

        def run(self):
            self.num += 1
            time.sleep(self.sleepTime)
            print('线程(%s),num=%d'%(self.name, self.num))

    if __name__ == '__main__':
        mutex = threading.Lock()
        t1 = MyThread(100,5)
        t1.start()
        t2 = MyThread(200,1)
        t2.start()

运行结果:

线程(Thread-2),num=201
线程(Thread-1),num=101

多线程全局变量

import threading
from time import sleep
def test(sleepTime):
    num = 1
    sleep(sleepTime)
    num+=1
    print('---(%s)--num=%d'%(threading.current_thread(), num))
if __name__ == '__main__':
    t1 = threading.Thread(target = test,args=(5,))
    t2 = threading.Thread(target = test,args=(1,))

    t1.start()
    t2.start()

运行结果:

---(<Thread(Thread-2, started 10876)>)--num=2
---(<Thread(Thread-1, started 7484)>)--num=2

同步应用

from threading import Thread,Lock
from time import sleep
class Task1(Thread):
    def run(self):
        while True:
            if lock1.acquire():
                print("------Task 1 -----")
                sleep(0.5)
                lock2.release()
class Task2(Thread):
    def run(self):
        while True:
            if lock2.acquire():
                print("------Task 2 -----")
                sleep(0.5)
                lock3.release()
class Task3(Thread):
    def run(self):
        while True:
            if lock3.acquire():
                print("------Task 3 -----")
                sleep(0.5)
                lock1.release()
#使用Lock创建出的锁默认没有“锁上”
lock1 = Lock()
#创建另外一把锁,并且“锁上”
lock2 = Lock()
lock2.acquire()
#创建另外一把锁,并且“锁上”
lock3 = Lock()
lock3.acquire()
t1 = Task1()
t2 = Task2()
t3 = Task3()
t1.start()
t2.start()
t3.start()

运行结果:

------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
------Task 1 -----
------Task 2 -----
------Task 3 -----
...........`

生产者与消费者模式

Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语(可以理解为原子操作,即要么不做,要么就做完),能够在多线程中直接使用。可以使用队列来实现线程间的同步。

import threading,time
from queue import Queue
class Producer(threading.Thread):
    def run(self):
        global queue
        count = 0
        while True:
            if queue.qsize() < 1000:
                for i in range(100):
                    count = count +1
                    msg = '生成产品'+str(count)
                    queue.put(msg)
                    print(msg)
            time.sleep(0.5)
class Consumer(threading.Thread):
    def run(self):
        global queue
        while True:
            if queue.qsize() > 100:
                for i in range(3):
                    msg = self.name + '消费了 '+queue.get()
                    print(msg)
            time.sleep(1)
if __name__ == '__main__':
    queue = Queue()
    for i in range(500):
        queue.put('初始产品'+str(i))
    for i in range(2):
        p = Producer()
        p.start()
    for i in range(5):
        c = Consumer()
        c.start()

运行结果:

生成产品1
生成产品2
生成产品1
生成产品3
生成产品2
生成产品4
Thread-3消费了 初始产品0
生成产品3
生成产品5
Thread-3消费了 初始产品1
生成产品4
生成产品6
Thread-4消费了 初始产品2
Thread-3消费了 初始产品3
生成产品5
生成产品7
Thread-4消费了 初始产品4
生成产品6
生成产品8
Thread-5消费了 初始产品5
Thread-4消费了 初始产品6
...........

Queue的说明

1.对于Queue,在多线程通信之间扮演重要的角色
2.添加数据到队列中,使用put()方法
3.从队列中取数据,使用get()方法
4.判断队列中是否还有数据,使用qsize()方法

上一篇下一篇

猜你喜欢

热点阅读