java程序员的python之路(线程)

本文详细介绍了线程和进程的概念及区别,通过实例演示了如何使用Python的threading模块进行多线程编程,并展示了线程同步的重要性和实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程和进程

有时候我们需要同时执行多个任务,可以使用多线程也可以使用多进程。
进程是由若干线程组成的,一个进程至少有一个线程。线程是操作系统执行的基本单元,进程是资源的集合。每个进程都有一个单独的内存空间,是一个独立程序的一次运行活动。也就是说多个进城之间是不共享数据的。我们在windows的任务管理器中,就可以查看到很多应用的进程。线程是进程中的执行调度单位,一个进程中可以有一个或者多个线程在执行。这些线程共享进程中的所有资源。python提供了两个模块支持线程。_thread和threading._thread比较低级,一般建议使用threading。

threading线程实现

直接看代码:

import queue
import threading
import time

class myThread(threading.Thread):
    def __init__(self,name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):
        #线程同步等待1秒钟,
        time.sleep(1)
        print("mythread")



thread1 = myThread("hello")
thread1.start()

#thread1加入当前线程,  当前线程等待thread1线程执行完毕后再继续执行。
thread1.join()

print("mainthread")  

输出结果如下:

mythread
mainthread

线程同步

上面提到了,多个线程是共享进程的资源的。多个线程又是同时执行的。那么问题就来了
举一个经典的例子:比如你有一个银行账号里存者100块钱。你用吃完饭要用支付宝支付20元,这个支付过程分3步走,
1.1:查询账户100元
1.2:100 - 20 = 80
1.3:更改账户余额为80元

但是就是你刚执行到第2步的时候,歇了一会儿,这时候你媳妇拿着银行卡去存50元钱,也分三步走
2.1:查询账户100元
2.2:100 + 50 = 150
2.3:更改账户余额为150元

你媳妇执行到第二步的时候,也歇了一会儿,这时候你执行了第三步,然后你媳妇也执行了第三步。这时候你的银行卡里就有150块钱,你白白吃了一顿饭。
模拟代码如下:

import queue
import threading
import time

#账户类
class Account():
    def __init__(self,num):
        self.num = num


#自己
class Myself(threading.Thread):
    def __init__(self,account):
        threading.Thread.__init__(self)
        self.account = account


    #消费20元
    def run(self):
        #查询账户余额
        num = self.account.num
        #支付20元
        num = num - 20

        #模拟歇一会儿
        time.sleep(1)

        #改变账户余额
        self.account.num = num


#媳妇       
class Wife(threading.Thread):
    def __init__(self,account):
        threading.Thread.__init__(self)
        self.account = account

    #存50元    
    def run(self):
        #查询账户余额
        num = self.account.num
        #存50元
        num = num + 50
        #模拟歇一会儿
        time.sleep(2)
        #改变账户余额
        self.account.num = num     

#创建锁       
threadLock = threading.Lock()
#创建账户 
account = Account(100)    
#创建线程
thread1 = Myself(account);     
thread2 = Wife(account);     
thread1.start()
thread2.start()

#等待线程结束
ts = (thread1,thread2)
for t in ts:
    t.join()


print(account.num)

输出结果如下:

150

当然银行是不允许这种情况发生的。那么怎么解决呢?那就是你在支付的过程中,把账户锁住,不允许其他人操作此账户,待你操作完成之后,其他人才能操作。这个锁住的过程就是线程同步。修改代码:

import queue
import threading
import time

#账户类
class Account():
    def __init__(self,num):
        self.num = num


#自己
class Myself(threading.Thread):
    def __init__(self,account):
        threading.Thread.__init__(self)
        self.account = account


    #消费20元
    def run(self):
        #加上锁
        threadLock.acquire()
        #查询账户余额
        num = self.account.num
        #支付20元
        num = num - 20

        #模拟歇一会儿
        time.sleep(1)

        #改变账户余额
        self.account.num = num
        #释放锁
        threadLock.release()


#媳妇       
class Wife(threading.Thread):
    def __init__(self,account):
        threading.Thread.__init__(self)
        self.account = account

    #存50元    
    def run(self):
        #加上锁
        threadLock.acquire()
        #查询账户余额
        num = self.account.num
        #存50元
        num = num + 50
        #模拟歇一会儿
        time.sleep(2)
        #改变账户余额
        self.account.num = num     
        #释放锁
        threadLock.release()

#创建锁       
threadLock = threading.Lock()
#创建账户 
account = Account(100)    
#创建线程
thread1 = Myself(account);     
thread2 = Wife(account);     
thread1.start()
thread2.start()

#等待线程结束
ts = (thread1,thread2)
for t in ts:
    t.join()


print(account.num)

输出结果如下:

130

condition

Python提供的Condition对象提供了对复杂线程同步问题的支持。Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。下面我们使用condition来实现一个线程安全的队列,使用这个队列来实现经典的生产者消费者问题。

import queue
import threading
import time

#同步队列
class ConcurrentQueue():
    def __init__(self,size):
        self.__size = size #队列容量
        self.__lock = threading.Lock() #锁
        self.__condition = threading.Condition(self.__lock)
        self.__queue = queue.Queue()



    def get(self):
        #是否获得锁成功
        if self.__condition.acquire():
            #如果队列为空,那么线程等待
            if self.__queue.empty():
                self.__condition.wait()

            #取得结果    
            result = self.__queue._get()

            #唤醒其他等待线程
            self.__condition.notifyAll()

            #释放锁
            self.__condition.release()

        return result;


    def put(self,element):
        #是否获得锁成功
        if self.__condition.acquire():
            #如果队列已满则等待
            if self.__queue.qsize() >= self.__size:
                self.__condition.wait()

            #存入数据    
            self.__queue.put(element)

            #唤醒其他线程
            self.__condition.notifyAll()

            #释放锁
            self.__condition.release()





#生产者
class Produce(threading.Thread):
    def __init__(self,queue):
        threading.Thread.__init__(self)
        self.__queue = queue
        self.__num = 0


    def run(self):
        while True:
            print("生产:"+str(self.__num)) 
            self.__queue.put(self.__num)
            self.__num += 1
            time.sleep(2)

#消费者
class Consumer(threading.Thread):
    def __init__(self,queue):
        threading.Thread.__init__(self)
        self.__queue = queue

    def run(self):
        while True:
            element = self.__queue.get()
            print("消费:"+str(element))       
            time.sleep(1)




q = ConcurrentQueue(10)

t1 = Produce(q)         
t2 = Consumer(q)   

t1.start()      
t2.start()

输出结果如下:

生产:0
消费:0
生产:1
消费:1
生产:2
消费:2
生产:3
消费:3
生产:4
消费:4
生产:5
消费:5
.......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值