Python多线程

 

线程:是进程中一个“单一连续的控制流”、执行路径

  • 线程又被称为轻量级进程
  • 一个进程可拥有多个并行的线程
  • 一个进程中的线程共享相同的内存单元、内存地址空间,可以访问相同的变量和对象,而且他们从同一堆中分配对象,通信、数据交换、同步操作,缺点线程是对全局变量随意修改,可能造成多线程之间对全局变量的混乱(不安全),可以通过传参的方式调用全局变量(不适用可变类型),但是修改次数过多,会有多次线程切换,产生紊乱
  • import threading,time
    g_num = 100
    
    def worker1():
        global g_num
        for i in range(3):
            g_num +=1
            print("in worker1,g_nun=%s"%g_num)
    def worker2():
        print("in worker2,g_nun=%s" % g_num)
    
    w1 = threading.Thread(target=worker1)
    w1.start()
    
    time.sleep(1)
    
    w2 = threading.Thread(target=worker2)
    w2.start()

    通过传参的方式调用局部变量: 

    import threading,time
    g_num = 100
    
    def worker1(num):
        for i in range(3):
            num +=1
            print("in worker1,g_nun=%s"%num)
    def worker2(num):
        print("in worker2,g_nun=%s" % num)
    
    w1 = threading.Thread(target=worker1,args=(g_num,))
    w1.start()
    
    time.sleep(1)
    
    w2 = threading.Thread(target=worker2,args=(g_num,))
    w2.start()

    给线程加锁 ,有时锁过多会出现死锁的问题。

    import threading,time
    g_num = 100
    
    def worker1(num):
        for i in range(300000):
            mutexFlag = mutex.acquire(True)
            if mutexFlag:
                num +=1
                mutex.release()
        print("in worker1,g_nun=%s" % num)
    def worker2(num):
        print("in worker2,g_nun=%s" % num)
    
    mutex = threading.Lock()
    w1 = threading.Thread(target=worker1,args=(g_num,))
    w1.start()

    给线程加锁,实现线程按顺序执行

  • from threading import Thread,Lock
    from time import sleep
    
    class Task1(Thread):
        def run(self):
            while True:
                if lock1.acquire():
                    print("--Task1--")
                    sleep(0.5)
                    lock2.release()
    
    class Task2(Thread):
        def run(self):
            while True:
                if lock2.acquire():
                    print("--Task2--")
                    sleep(0.5)
                    lock3.release()
    
    class Task3(Thread):
        def run(self):
            while True:
                if lock3.acquire():
                    print("--Task3--")
                    sleep(0.5)
                    lock1.release()
    
    lock1 = Lock()
    lock2 = Lock()
    lock2.acquire()
    lock3 = Lock()
    lock3.acquire()
    
    t1 = Task1()
    t2 = Task2()
    t3 = Task3()
    t1.start()
    t2.start()
    t3.start()

 

  • 由于线程间的通信是在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简单而且信息传递的速度也更快
  • 有三种状态,就绪,阻塞,运行

线程和进程的区别

  • 进程是系统进行资源分配和调度的一个独立单位(资源分配)
  • 进程在执行过程中拥有独立的内存单元,多个线程共享内存,从而极大的提高了程序的运行效率
  • 一个程序至少有一个进程,一个进程至少有一个线程
  • 线程是进程的一个实体,CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位(调度执行)
  • 线程自己基本不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程贡献进程所有的全部资源
  • 线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高
  • 线程不能独立运行,必须依存在进程中
  • 线程和进程在使用时各有优缺点,线程执行开销小,但不利于资源的管理和保护,而进程则相反。

 

  线程的数量

  • import threading
    import time
    
    def saySorry():
        for i in range(1, 5):
            print("I'm sorry*")
            time.sleep(1)
    
    def getOut():
        for i in range(1, 5):
            print("get out of my sight*")
            time.sleep(2)
    
    if __name__ == "__main__":
        t1 = threading.Thread(target=saySorry)
        t2 = threading.Thread(target=getOut)
        t1.start()#启动线程
        t2.start()#启动线程
    
        while True:
            length = len(threading.enumerate())
            print("当前的线程数量:%s"%length)
            if length <= 1:
                break
            time.sleep(0.5)

线程子类化,改写run() ,如果要传参,则改写__init__方法

  • import threading
    import time
    
    class MyThread(threading.Thread):
        def run(self):
            for i in range(3):
                time.sleep(1)
                msg = "I am "+self.name+"@"+str(i)
                print(msg)
    
    
    if __name__ == "__main__":
        t = MyThread()
        t.start()

queue实现线程按照顺序执行

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

ThreadLocal变量

一个ThreadLocal变量虽然是全局变量,但是每个线程都只能读写自己线程的独立副本,互不干扰,ThreadLocal结局了参数在一个线程中各个函数之间相互传递的问题,可以理解ThreadLocal是一个dict,可以绑定其他变量。ThreadLocal最常用到的地方是为每个线程绑定一个数据库链接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数,都可以非常方便的访问这些资源

  • import threading
    #创建ThreLocal
    localschool = threading.local()
    def processStudent():
        name = localschool.student
        print("hello!%s in %s"%(name,threading.current_thread().name))
    def processThread(name):
        localschool.student = name
        processStudent()
    
    t1 = threading.Thread(target=processThread,args=("zs",),name="t1")
    t2 = threading.Thread(target=processThread,args=("ww",),name="t2")
    t1.start()
    t2.start()
    t1.join()
    t2.join()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值