码迷,mamicode.com
首页 > 编程语言 > 详细

python__系统 : 线程

时间:2018-05-25 01:35:48      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:方式   col   重写   互斥   global   info   避免   传递   死锁   

线程之间,全局变量可以共享,但是局部变量依然是不共享的,线程的创建方式: threading.Thread(),还可以定义一个类继承Thread,重写他的run方法,具体和进程的写法一样.

那么,线程之前全局变量共享,如果两个线程同时修改一个全局变量,就会有一些麻烦,所以需要用到互斥锁:

from threading import Thread, Lock
import time

g_num = 0

def test1():
    global g_num
    mutex.acquire()           <------------------------------
    for i in range(1000000):
        g_num += 1
    mutex.release()          <-----------------------------
    print(g_num)

def test2():
    global g_num
    mutex.acquire()       <----------------------
    for i in range(1000000):
        g_num += 1
    mutex.release()       <------------------------
    print(g_num)

mutex = Lock()

t1 = Thread(target=test1)
t1.start()

t2 = Thread(target=test2)
t2.start()

>>>185734 1
   1000000
   2000000

Lock() 是创建一把锁,用acquire() 的方式加锁 , release() 的方式解锁.  如果一个线程对一个变量加锁,剩下的线程就只能在等待,解锁之后用通知(还有一种耗费资源的方式是轮询) 的方式给等待的线程传递信息,锁已经解开.

需要注意应该避免死锁, Lock 的 acquire() 里面有两个参数 blocking=True 默认是True 如果已经上锁,那么就一直在这等,等到锁解开为止,也就是堵塞. 改成False 的话如果已上锁那么就跳过这个加锁操作,所以一般搭配 if 使用 加锁成功返回值True. 还有一个参数timeout=-1 ,默认-1.就是延迟,如果改成正数,那么就会在等待多少秒之后才放弃加锁.

同步 : 协同步调,按预定的先后次序运行. 异步:不确定什么时候运行.

threading.local() 创建一个对象,里面可以保存一些类似字典一样的参数,如 localVal = threading.local()

localVal.val = name这条语句可以储存一个变量到当前线程,如果在另外一个线程里面再次对localVal.val进行赋值,

那么会在另外一个线程单独创建内存空间来存储,也就是说在不同的线程里面赋值 不会覆盖之前的值,因为每个

线程里面都有一个单独的空间来保存这个数据,而且这个数据是隔离的,其他线程无法访问,就像这张图一样:

技术分享图片

最后,生产者与消费者模型:

from queue import Queue
import time, threading

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(0.5)


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()

from queue import Queue (python2 是 from Queue) 这是队列,先进先出,用来缓冲数据, 有 get put qsize 等方法,和进程的那个进程间通信的队列(from multiprocessing import Queue) 基本一样.

思路理解即可.

 

python__系统 : 线程

标签:方式   col   重写   互斥   global   info   避免   传递   死锁   

原文地址:https://www.cnblogs.com/cccy0/p/9085992.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!