python线程初学

python线程初学

  • 1.线程概念
  • 2.线程基本实现方式
    • 函数方式
    • 用类来包装线程对象
  • 3.线程同步
    • 线程锁同步
    • 条件变量同步

1. 线程基本概念

线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。线程是程序级别的概念,一个程序可以有多个线程同时执行(子功能可以同时执行)。
线程分为程序主线程和子线程两种。任何进程都会自动启动唯一的主线程。主线程可以随意启动多个子线程。
一个Python脚本程序运行,Python虚拟机就启动了一个进程,同时启动一个主线程mainTread。
我们可以在一个python程序中创建多个子线程,每个子线程启动由程序指令控制。

2.线程基本实现方式

Python通过两个标准库_thread和threading提供对线程的支持。

2.1 函数方式实现多线程

_thread提供了低级别的、原始的线程以及一个简单的锁。
以下为基本代码实现

import _thread        #引入线程模块
import time

#定义线程函数:就是用来封装子线程执行的代码
def workFunction(threadName,delay):
    print("线程"+threadName+"启动执行:")
    time.sleep(1)
    print("线程代码执行完成,子线程退出销毁")
    pass

if __name__=="__main__":
    #启动多个子线程
    _thread.start_new_thread(workFunction, ('线程1',0.001)) #启动第一个子线程
    _thread.start_new_thread(workFunction, ('线程2', 0.001)) #启动第一个子线程
    while True:
        print("主线程在running!!!!!")
        time.sleep(0.1)
        pass

2.2 模块实现多线程

threading 模块提供的方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
以下为基本代码实现

import threading
import time
#定义煮水的线程
class BoilWatter(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        pass

    def run(self):
        print("开始煮水。")
        time.sleep(10)  #wait状态
        print("煮水结束。")
        pass
    pass

#定义洗杯子的线程类
class WashCup(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        pass

    def run(self):#不能带参数
        for i in range(3):
            print("洗第{0}个杯子".format(i+1))
            time.sleep(3)
            print("洗完第{0}个杯子".format(i+1))
            pass
        print()
        pass
    pass


if __name__=="__main__":

    thread1=BoilWatter()
    thread2 = WashCup()
    thread1.start()
    thread2.start()

3.线程同步

多个线程在执行的时候为随机模式,有哪个线程占用CPU我们无法进行控制。但如果需要强行要求某一个线程执行完毕后再执行另一个线程,这种情况就需要使用线程同步技术。
Python的线程同步技术有两种比较典型的解决方案:锁同步 和 条件变量同步。
锁:将一个线程的run()方法进行锁定,在全部执行完毕后在解除锁定。这样其他线程在执行的时候需要等待解除锁定后方可继续执行(锁定和解锁必须成对出现,否则出现“死锁”)。

3.1线程锁同步

线程锁对象 = Threading.Lock()
线程锁对象.acquire() # 锁定
线程锁对象.release() # 解除锁定

import threading
import time
#定义抢票线程类
lock = threading.Lock()  # 共享内存锁
class OrderTicket(threading.Thread):

    tickets=1000

    def __init__(self,name):
        threading.Thread.__init__(self)
        self.__name=name
        pass

    def run(self):
        #lock.acquire()
        while OrderTicket.tickets>0:
            #time.sleep(0.001)
            lock.acquire()                          #同步导致并发效率降低
            if OrderTicket.tickets>0:
                OrderTicket.tickets-=1
                print("{0}抢到一张票,剩下{1}".format(self.__name,OrderTicket.tickets))
            lock.release()
            time.sleep(0.01)
            pass

        pass
    pass

3.2条件变量同步

Python提供的Condition对象提供了对复杂线程同步问题的支持。
Condition被称为条件变量,除了提供与Lock类似的 acquire和release方法外,还提供了wait和notify方法。


条件变量同步工作原理:线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则 wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复 这一过程,从而解决复杂的同步问题。

import threading
import time
import random

#使用共享区模拟变量
count=0
#创建条件对象
condition=threading.Condition()

class Producer(threading.Thread):
    def __init__(self,threadName):
        threading.Thread.__init__(self)
        self.threadName=threadName
        pass

    def run(self):
        global count
        while True:
            if condition.acquire():
                if count>=10:
                    print('共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!')
                    condition.wait()
                else:
                    count+=1
                    msg=time.ctime()+' '+self.threadName+'生产了1件商品放入共享区,共享区总计商品个数:',count
                    print(msg)
                    condition.notify()
                condition.release()
                time.sleep(random.randrange(10)/5)
        pass
    pass

你可能感兴趣的:(python线程基础)