Python中的多进程与多线程(三)

Python中的多进程与多线程(三)

Python实现多线程

一、背景了解

  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。在前面的博客中有提到,进程是由若干线程组成的,一个进程至少含有一个线程。

  • 多线程类似于同时执行多个不同程序,多线程运行有以下优点:

    • 使用线程可以把占据长时间的任务放到后台去处理

    • 程序的运行速度可能会加快

    • 在一些等待的任务实现上比如用户输入、文件读写和网络数据收发等,线程就比较有用。在这种情况下通过多线程可以释放一些珍贵的资源如内存占用等

    • 用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度

  • 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制

  • 每个线程都有它自己的一组CPU寄存器,称为线程的上下文,指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器

  • 线程可以分为:

    • 内核线程:由操作系统内核创建和撤销

    • 用户线程:不需要内核支持而在用户程序中实现的线程

  • 线程具有以下特点:

    • 线程可以被抢占(中断)

    • 在其它线程运行时,线程可以暂时搁置(也称为睡眠)(线程的退让)

二、Python多线程编程

1、threading

  • Python标准库中提供了threading模块,对多线程编程提供了很大的支持

  • 下面使用threading模块实现多线程:

import time, threading

def test(index):
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    print("Thread %s starts..." % threading.current_thread().name)
    print("Index : %s..." % index)
    time.sleep(3)
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    print("Thread %s ends..." % threading.current_thread().name)


if __name__ == "__main__":
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    print("Thread %s starts..." % threading.current_thread().name)
    #创建线程
    th = threading.Thread(target=test, args=(1, ), name="test_thread")
    time.sleep(2)
    #启动线程
    #等待线程执行结束
    th.join()
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    print("Thread %s ends..." % threading.current_thread().name)
  • 运行结果:
2018-09-30 21:33:58
Thread MainThread starts...
2018-09-30 21:34:00
Thread test_thread starts...
Index : 1...
2018-09-30 21:34:03
Thread test_thread ends...
2018-09-30 21:34:03
Thread MainThread ends...

2、Lock

  • 多进程与多线程的最大不同在于,多进程中,同一个变量,各自有一份拷贝存放于每个进程中,互不影响。而多线程中,所有变量都由所有线程共享,所以,任何一个共享变量都可以被任何一个线程修改。因此线程之间共享数据最大的危险在于多个线程同时改变一个变量。为了解决这个问题,我们可以借助于threading模块的Lock类来给共享变量加锁

  • 下面给出使用Lock对共享变量进行加锁的示例:

import threading

class Account:
    def __init__(self):
        self.balance = 0

    def add(self, lock):
        #获得锁
        lock.acquire()
        for i in range(0,100000):
            self.balance += 1
        #释放锁
        lock.release()

    def delete(self, lock):
        lock.acquire()
        for i in range(0,100000):
            self.balance -=1
        lock.release()

if __name__ == "__main__":

    account = Account()
    lock = threading.Lock()

    #创建线程
    thread_add = threading.Thread(target=account.add, args=(lock, ), name='Add')
    thread_del = threading.Thread(target=account.delete, args=(lock, ), name='Delete')

    #启动线程
    thread_add.start()
    thread_del.start()

    #等待线程结束
    thread_add.join()
    thread_del.join()

    print(account.balance)

猜你喜欢

转载自blog.csdn.net/J__Max/article/details/82913749