python中的多线程

Python的多线程适用于I/O密集型任务,因为python有GIL锁,该锁为了保证线程的安全,同一时刻只有一个线程被CPU执行。

调用函数实现多线程:

#coding:utf-8

# python主程序也属于一个线程
import threading #线程模块
import time

def Hi(num):       
    print("hello %d\n"%num)
    time.sleep(3)

if __name__ == '__main__':

    t1=threading.Thread(target=Hi,args=(10,))#创建了一个线程对象t1
    t1.start()          # 运行线程

    t2 = threading.Thread(target=Hi, args=(9,))  # 创建了一个线程对象t1
    t2.start()       # 运行线程

    print("ending..........")    主线程  
#hello 10   
#hello 9  同时输出  hello9 hello10,ending
#ending..........  过3秒后程序结束

用类实现多线程

# coding:utf-8
import threading
import time

class MyThread(threading.Thread):      # 定义类并继承threading.Thread类
    def __init__(self, num):
        threading.Thread.__init__(self)   # 调用父类构造函数
        self.num = num

    def run(self):           #  必须定义每个线程要运行的函数run
        print("running on number:%s" % self.num)
        time.sleep(3)

if __name__ == '__main__':
    t1 = MyThread(1)   # 生成线程对象t1
    t2 = MyThread(2)   # 生成线程对象t2
    t1.start()      # 运行
    t2.start()

    print("ending......")   
    #running on number:1  同时输出,3秒后程序结束
    #running on number:2ending......

join方法让其他线程等待

#coding:utf-8

import threading
import time

def music():
    print("begin to listen %s"%time.ctime())
    time.sleep(3)
    print("stop to listen %s" % time.ctime())


def game():
    time.sleep(4)
    t3=threading.Thread(target=music)  # 创建线程t3
    t3.start()    

    print("begin to play game %s"%time.ctime())
    time.sleep(5)
    print("stop to play game %s" % time.ctime())


if __name__ == '__main__':

    t1=  threading.Thread(target=music)

    t2 = threading.Thread(target=game)

    t1.start()
    t2.start()

    t1.join()   #  join函数让其他未join线程等待该进程结束
    t2.join()   

    print("ending")
# 输出:
begin to listen Sat Mar 24 21:57:02 2018
stop to listen Sat Mar 24 21:57:05 2018
begin to listen Sat Mar 24 21:57:06 2018begin to play game Sat Mar 24 21:57:06 2018

stop to listen Sat Mar 24 21:57:09 2018
stop to play game Sat Mar 24 21:57:11 2018
ending

设置守护线程

一般的主线程,必须等所有子线程程结束后自己才能结束,但是当某个子线程被设置成守护线程时,主线程不必等该线程结束,该线程会守护主动随着主线程的结束而结束。

import threading
from time import ctime,sleep
import time

def ListenMusic(name):

        print ("Begin listening to %s. %s" %(name,ctime()))
        sleep(3)
        print("end listening %s"%ctime())


def RecordBlog(title):

        print ("Begin recording the %s! %s" %(title,ctime()))
        sleep(5)
        print('end recording %s'%ctime())

threads = []

t1 = threading.Thread(target=ListenMusic,args=('水手',))  #args线程执行函数传参
t2 = threading.Thread(target=RecordBlog,args=('python线程',))

threads.append(t1)     #将t1,t2加入线程队列
threads.append(t2)

if __name__ == '__main__':
    #t1.setDaemon(True)
    t2.setDaemon(True)

    for t in threads:   # 从线程队列中读取数据
        t.setDaemon(True) #注意:设置守护线程一定在start之前设置
        t.start()
        print(t.getName())
        print("count:",threading.active_count())   # 统计运行线程数
        #t.join()#此处加join的话,会变成串行
    #t.join()

    t1.join()   # 让主线程等待
    #t1.setDaemon(True)

    #t2.join()########考虑这三种join位置下的结果

    while threading.active_count()==1:

        print ("all over %s" %ctime())

多线程导致数据不可重复读

由于多线程并发执行,可能导致数据读取与写入时出现顺序错误导致结果不可重复读,代码演示如下

import threading
import time
def sub():
    global num
    temp=num
    time.sleep(0.0001)
    num=temp-1

num=100

l=[]

for i in range(100):
    t=threading.Thread(target=sub)
    t.start()
    l.append(t)

for t in l:
    t.join()

print(num)

利用加锁机制处理线程同步

import threading
import time
def sub():
    global num

    lock.acquire()   # 获得锁
    temp=num        # 操作数据
    time.sleep(0.0001)    
    num=temp-1
    lock.release()   # 释放锁

num=100

l=[]
lock=threading.Lock()   # 用threading.Lock()产用生一把锁

for i in range(100):
    t=threading.Thread(target=sub)
    t.start()
    l.append(t)

for t in l:
    t.join()

print(num)

利用信号量实现线程同步

import threading,time

class myThread(threading.Thread):
    def run(self):

        if semaphore.acquire():
            print(self.name)
            time.sleep(3)
            semaphore.release()

if __name__=="__main__":
    semaphore=threading.Semaphore()

    thrs=[]
    for i in range(100):
        thrs.append(myThread())
    for t in thrs:
        t.start()

用于实现线程通信的队列用法

import queue      #  线程 队列

q=queue.Queue(3)  # FIFO模式

q.put(12)
q.put("hello")
q.put({"name":"yuan"})
# q.put_nowait(56)#  q.put(block=False)

print(q.qsize())
print(q.empty())
print(q.full())
# q.put(34,False)


while 1:
    data=q.get()
    print(data)
    print("----------")

用event事件同步线程对象

import threading,time
class Boss(threading.Thread):

    def run(self):
        print("BOSS:今晚大家都要加班到22:00。")
        print(event.isSet())# False
        event.set()
        time.sleep(5)
        print("BOSS:<22:00>可以下班了。")
        print(event.isSet())
        event.set()

class Worker(threading.Thread):
    def run(self):

        event.wait()#    一旦event被设定,等同于pass

        print("Worker:哎……命苦啊!")
        time.sleep(1)
        event.clear()
        event.wait()
        print("Worker:OhYeah!")


if __name__=="__main__":
    event=threading.Event()


    threads=[]
    for i in range(5):
        threads.append(Worker())
    threads.append(Boss())
    for t in threads:
        t.start()
    for t in threads:
        t.join()

    print("ending.....")
# 输出:
BOSS:今晚大家都要加班到22:00False
Worker:哎……命苦啊!
Worker:哎……命苦啊!
Worker:哎……命苦啊!
Worker:哎……命苦啊!
Worker:哎……命苦啊!
BOSS:<22:00>可以下班了。
False
Worker:OhYeah!
Worker:OhYeah!
Worker:OhYeah!
Worker:OhYeah!
Worker:OhYeah!
ending.....

用递归锁防止线程死锁

import threading
import time


class MyThread(threading.Thread):

    def actionA(self):

        r_lcok.acquire() #count=1
        print(self.name,"gotA",time.ctime())
        time.sleep(2)
        r_lcok.acquire() #count=2

        print(self.name, "gotB", time.ctime())
        time.sleep(1)

        r_lcok.release() #count=1
        r_lcok.release() #count=0


    def actionB(self):

        r_lcok.acquire()
        print(self.name, "gotB", time.ctime())
        time.sleep(2)

        r_lcok.acquire()
        print(self.name, "gotA", time.ctime())
        time.sleep(1)

        r_lcok.release()
        r_lcok.release()


    def run(self):

        self.actionA()
        self.actionB()


if __name__ == '__main__':

    # A=threading.Lock()
    # B=threading.Lock()

    r_lcok=threading.RLock()
    L=[]

    for i in range(5):
        t=MyThread()
        t.start()
        L.append(t)


    for i in L:
        i.join()

    print("ending....")

生产者消费者模型

import time,random
import queue,threading

q = queue.Queue()

def Producer(name):
  count = 0
  while count <10:
    print("making........")
    time.sleep(5)
    q.put(count)
    print('Producer %s has produced %s baozi..' %(name, count))
    count +=1
    #q.task_done()
    q.join()
    print("ok......")

def Consumer(name):
  count = 0
  while count <10:
        time.sleep(random.randrange(4))
    # if not q.empty():
    #     print("waiting.....")
        #q.join()
        data = q.get()
        print("eating....")
        time.sleep(4)

        q.task_done()
        #print(data)
        print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))
    # else:
    #     print("-----no baozi anymore----")
        count +=1

p1 = threading.Thread(target=Producer, args=('A君',))
c1 = threading.Thread(target=Consumer, args=('B君',))
c2 = threading.Thread(target=Consumer, args=('C君',))
c3 = threading.Thread(target=Consumer, args=('D君',))

p1.start()
c1.start()
c2.start()
c3.start()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值