python__系统 : 线程

2018-06-18 03:05:19来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

线程之间,全局变量可以共享,但是局部变量依然是不共享的,线程的创建方式: 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) 基本一样.

思路理解即可.

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:python 脚本生成随机 字母 + 数字密码

下一篇:python面向对象基础