Python3-threading模块-多线程

什么是线程?

  线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务

Python3中实现多线程有两种方式

  1.直接实例化threading.Thread线程对象,实现多线程

import threading
import time


def print_age(who, age):
    """
    需要用多线程调用的函数
    :param who:
    :param age:
    :return:
    """
    print("Hello,every one!")
    time.sleep(1)
    print("%s is %s years old !" % (who, age))

if __name__ == "__main__":
    t1 = threading.Thread(target=print_age, args=("jet", 18, ))     # 创建线程1
    t2 = threading.Thread(target=print_age, args=("jack", 25, ))    # 创建线程2
    t3 = threading.Thread(target=print_age, args=("jack", 25,))     # 创建线程3
    t1.start()    # 运行线程1
    t2.start()    # 运行线程2
    t3.start()    # 运行线程3
    print("over...")
View Code

  2.通过继承threading.Thread,并重写run()方法,来实现多线程

import threading
import time


class MyThread(threading.Thread):
    """
    使用继承的方式实现多线程
    """
    def __init__(self, who):
        super().__init__()    # 必须调用父类的构造方法
        self.name = who

    def run(self):
        print("%s is run..." % self.name)
        time.sleep(3)

if __name__ == "__main__":
    t1 = MyThread("Jet")    # 创建线程1
    t2 = MyThread("Jack")   # 创建线程2
    t1.start()              # 运行线程1
    t2.start()              # 运行线程2
    print("over...")
View Code

守护线程

  可以通过setDaemon()方法将线程设置为守护线程,当守护线程退出时,由它启动的其它子线程将同时退出,不管是否执行完成

import threading
import time


def print_age(who, age):
    print("Hello,every one!")
    time.sleep(1)
    print("%s is %s years old !" % (who, age))


def daemon_func():
    for i in range(18, 25):
        t = threading.Thread(target=print_age, args=("Jet", i,))  # 创建线程
        t.start()


if __name__ == "__main__":
    dt = threading.Thread(target=daemon_func)     # 创建线程
    dt.setDaemon(True)      # 设置为守护线程
    dt.start()
    dt.join(timeout=2)
    print("over...")
View Code

线程锁

  因为多线程是共享父进程里面的数据的,所以当多个线程同时修改一份数据的时候,就容易出错,因此就有了锁,锁能确保在同一时间只有一个线程修改这份数据

  CPython的GIL(Global Interpreter Lock)是全局线程锁,是确保只有一个线程运行的,与这个锁没有关系,锁的层级不一样,GIL更为底层

# -*- coding: utf-8 -*-
import threading
import time


def add_one():
    global num
    print("Value: %s" % num)
    time.sleep(1)
    lock.acquire()    # 加锁
    num += 1          # 修改数据
    lock.release()    # 释放锁


if __name__ == "__main__":
    num = 0
    lock = threading.RLock()     # 一般都用RLock递归锁
    thread_list = []
    for i in range(100):
        t = threading.Thread(target=add_one)
        t.start()
        thread_list.append(t)
    for i in thread_list:
        i.join()
    print("Num = %s" % num)
View Code

信号量

  信号量semaphore,是一个变量,控制着对公共资源或者临界区的访问。信号量维护着一个计数器,指定可同时访问资源或者进入临界区的线程数。用来控制最大线程数的

# -*- coding: utf-8 -*-
import threading
import time


def add_one():
    global num
    semaphore.acquire()    # 加锁,最多有五个线程做以下操作
    time.sleep(1)
    num -= 1
    print("Value: %s" % num)
    semaphore.release()    # 释放锁


if __name__ == "__main__":
    num = 100
    thread_list = []
    semaphore = threading.BoundedSemaphore(5)

    for i in range(100):
        t = threading.Thread(target=add_one)
        t.start()
        thread_list.append(t)
    for i in thread_list:
        i.join()        # 等待线程结束
    print("Num = %s" % num)
View Code

参考资料

  http://python.usyiyi.cn/translate/python_352/library/threading.html

posted on 2017-04-14 17:25  AustralGeek  阅读(3052)  评论(0编辑  收藏  举报

导航