美文网首页
Python 多线程编程2

Python 多线程编程2

作者: 一个扫地的垃圾 | 来源:发表于2020-03-22 14:32 被阅读0次

1 守护线程

守护线程(Daemon thread),又叫做后台线程。此类线程的特点是当其他线程都执行结束时,无论守护线程是否完成,都直接结束当前工作。例如,python中的垃圾回收机制就是守护线程的代表,当主线程和其他线程完成工作后,垃圾回收机制也就没有再继续执行的必要了。

创建守护线程可以在创建线程时,将daemon属性值设置为True,下面的例子展示了如何创建守护线程。

# coding:utf-8
import threading
def action(length):
    for i in range(length):
        print(threading.current_thread())
if __name__ == "__main__":
    t = threading.Thread(target=action, args=(20,), daemon=True)
    # t.daemon = True  # 此中方法也可以开启守护线程
    t.start()
    for i in range(5):
        print(threading.current_thread())

输出结果:

<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<Thread(Thread-1, started daemon 123145454514176)>
<_MainThread(MainThread, started 4672699840)><Thread(Thread-1, started daemon 123145454514176)>
<_MainThread(MainThread, started 4672699840)>
<_MainThread(MainThread, started 4672699840)>
<_MainThread(MainThread, started 4672699840)>
<_MainThread(MainThread, started 4672699840)>

2 互斥锁

互斥锁用于解决线程之间数据不同步的问题,例如给出下面一段代码,用于模仿银行用户取钱的操作:

# coding:utf-8
import threading
import time


class Account(object):
    """
    定义账户的类
    """
    def __init__(self, account_no, balance):
        """
        :param account_no: 唯一的账户号
        :param balance: 账户对应的余额
        """
        self.account_no = account_no
        self.balance = balance


def withdraw(account, draw_amount):
    """
    取钱操作
    :param account: 账户类的实例化对象
    :param draw_amount: 取钱金额
    :return: None
    """
    if account.balance >= draw_amount:
        print(threading.current_thread().getName() + " Withdraw success ", draw_amount)
        time.sleep(0.5)  # sleep函数会使当前线程阻塞,从而切换到另一线程
        account.balance -= draw_amount
        print("balance is ", account.balance)
    else:
        print("Withdraw failure")


if __name__ == "__main__":
    # 创建一个账户,两个用户分别取钱,会出现数据不同步引发的错误
    acc = Account("62102034", 1000)  # 创建账户,包含两个属性,账户号和余额
    th1 = threading.Thread(target=withdraw, args=(acc, 800))
    th2 = threading.Thread(target=withdraw, args=(acc, 800))
    th1.start()
    th2.start()

输出结果:

Thread-1 Withdraw success  800
Thread-2 Withdraw success  800
balance is  200
balance is  -600

此时会出现一个问题,当第一个线程执行余额和取钱数目判断操作时,系统判定可以成功取钱,但是紧接着执行了一个sleep的函数使得当前线程进入阻塞状态,第二个线程重复上述操作,最后造成了两个线程同时可以成功取钱。threading模块引入RLock类可以锁定当前进程,从而可以实现在一个线程上实现独享数据。

lock = threading.RLock()类构建一个互斥锁的对象,用于锁定当前进程的数据
lock.acquire() 对lock对象加锁
lock.release() 对lock对象释放锁
acquire和release方法必须成对出现

RLock对象的acquirerelease方法必须成对出现,同时将两个方法应用到线程执行的函数体中,就可以实现对线程加锁。

# coding:utf-8
import threading
import time


class Account(object):
    # 定义账户的类
    def __init__(self, account_no, balance):
        """定义构造器"""
        self.account_no = account_no
        self._balance = balance  # 为了账户安全,定义余额为类的内部属性,
        self.lock = threading.RLock()  # 定义lock属性为互斥锁对象

    def withdraw(self, withdraw_amount):
        """
        取钱操作
        :param withdraw_amount: 取钱金额
        :return: None
        """
        self.lock.acquire()  # 线程加锁
        if self._balance >= withdraw_amount:
            print(threading.current_thread().getName(), " Withdraw success ", withdraw_amount)
            time.sleep(0.5)
            self._balance -= withdraw_amount  # 更新余额
            print("balance is ", self._balance)
        else:
            print(threading.current_thread().getName(), "Withdraw failure")
        self.lock.release()  # 线程释放锁


if __name__ == "__main__":
    acc = Account("62102034", 1000)
    th1 = threading.Thread(target=acc.withdraw, args=(800,))
    th2 = threading.Thread(target=acc.withdraw, args=(800,))
    th1.start()
    th2.start()

输出结果:

Thread-1  Withdraw success  800
balance is  200
Thread-2 Withdraw failure

另外,也可以使用上一小节提到的join方法应用到某一个线程,使其优先占用CPU资源完成当前线程工作。

# coding:utf-8
import threading
import time


class Account(object):
    # 定义账户的类
    def __init__(self, account_no, balance):
        """定义构造器"""
        self.account_no = account_no
        self._balance = balance  # 为了账户安全,定义余额为类的内部属性,
        self.lock = threading.RLock()  # 定义lock属性为互斥锁对象

    def withdraw(self, withdraw_amount):
        """
        取钱操作
        :param withdraw_amount: 取钱金额
        :return: None
        """
        # self.lock.acquire()  # 线程加锁
        if self._balance >= withdraw_amount:
            print(threading.current_thread().getName(), " Withdraw success ", withdraw_amount)
            time.sleep(0.5)
            self._balance -= withdraw_amount  # 更新余额
            print("balance is ", self._balance)
        else:
            print(threading.current_thread().getName(), "Withdraw failure")
        # self.lock.release()  # 线程释放锁


if __name__ == "__main__":
    acc = Account("62102034", 1000)
    th1 = threading.Thread(target=acc.withdraw, args=(800,))
    th2 = threading.Thread(target=acc.withdraw, args=(800,))
    th1.start()
    th1.join()
    th2.start()

输出结果:

Thread-1  Withdraw success  800
balance is  200
Thread-2 Withdraw failure

相关文章

  • 5-线程(补充)

    Python多线程原理与实战 目的: (1)了解python线程执行原理 (2)掌握多线程编程与线程同步 (3)了...

  • 多线程

    Python多线程原理与实战 目的: (1)了解python线程执行原理 (2)掌握多线程编程与线程同步 (3)了...

  • Python多线程编程——多线程编程中的加锁机制

    如果大家对Python中的多线程编程不是很了解,推荐大家阅读之前的两篇文章:Python多线程编程——多线程基础介...

  • python多线程入门之旅一

    所有代码来自python核心编程 参考python核心编程一书,学习多线程工作模式,多线程实现主要模块thread...

  • Python 3 多线程编程

    本文主要基于python 3.5实现多线程编程 1. 创建多线程 2. 多线程间的同步,lock机制 3. que...

  • Python 并行编程

    多线程编程 Python 主要提供了包括thread、threading、Queue等多线程编程模块。thread...

  • Python学习笔记-第12天:异步编程(2)和单元测试

    第十二天 异步编程(2)和单元测试 今天计划学习Python的多线程编程异步编程,学习项目及练习源码地址:GitH...

  • Python 多线程编程2

    1 守护线程 守护线程(Daemon thread),又叫做后台线程。此类线程的特点是当其他线程都执行结束时,无论...

  • Python 并发编程简介

    1 多线程和多进程 Python语言中既有多线程编程也有多进程编程,也叫做并发编程。 多进程 把一个程序分成几个不...

  • Python多线程编程(一)

    1. threading模块 Python 实现多线程编程可以通过thread模块(thread模块在Python...

网友评论

      本文标题:Python 多线程编程2

      本文链接:https://www.haomeiwen.com/subject/kixvyhtx.html