进程与线程 -- 多线程

  • 进程是由若干线程组成的,一个进程至少有一个线程
  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。
  • Python的线程是真正的Posix Thread,而不是模拟出来的线程。
为什么使用多线程
  • 多进程和多线程都可以完同时执行多任务的功能
  • 创建进程的系统开销非常大,是一种重量级的多任务方式
  • 进程间的内存空间是相互独立的,数据不能共享
  • 线程属性某个进程,创建线程的系统开销比较小,是一种轻量级的多任务方式
  • 线程间共享所属进程的内存空间,数据可以共享
threading模块

Python提供了两个线程模块:_threadthreading

  • _thread是低级模块
  • threading是高级模块(推荐使用)
使用threading模块中的Thread类
  • 实例演示
import time, threading

def loop():  # 新线程执行的代码
    print('thread %s is running...' % threading.current_thread().name)
    n = 0
    while n < 5:
        n = n + 1
        print('thread %s >>> %s' % (threading.current_thread().name, n))
        time.sleep(1)
    print('thread %s ended.' % threading.current_thread().name)

print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
thread MainThread is running...
thread LoopThread is running...
thread LoopThread >>> 1
thread LoopThread >>> 2
thread LoopThread >>> 3
thread LoopThread >>> 4
thread LoopThread >>> 5
thread LoopThread ended.
thread MainThread ended.
  • 任何进程都默认启动一个线程,称为主线程,主线程可以启动子线程
  • current_thread()函数,返回当前线程名,主线程名为MainThread
  • 子线程名在创建时指定,如不指将自动命名为Thread-1,Thread-2
查看线程数量
import threading
from time import sleep,ctime

def sing():
    for i in range(3):
        print("正在唱歌...%d"%i)
        sleep(1)

def dance():
    for i in range(3):
        print("正在跳舞...%d"%i)
        sleep(1)

if __name__ == '__main__':
    print('---开始---:%s'%ctime())

    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)

    t1.start()
    t2.start()

    while True:
        length = len(threading.enumerate())
        print('当前运行的线程数为:%d'%length)
        if length<=1:
            break

        sleep(0.5)
---开始---:Mon Jan  7 22:49:59 2019
正在唱歌...0
正在跳舞...0
当前运行的线程数为:3
当前运行的线程数为:3
正在跳舞...1
正在唱歌...1
当前运行的线程数为:3
当前运行的线程数为:3
当前运行的线程数为:3
正在唱歌...2
正在跳舞...2
当前运行的线程数为:3
当前运行的线程数为:3
当前运行的线程数为:1
线程的封装

为了体现封装性,使用threading模块时,通常会定义一个子类,让它继承自threading.Thread类,并重写run方法

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = "I'm "+self.name+' @ '+str(i)  #name属性中保存当前线程名
            print(msg)

if __name__ == '__main__':
    t = MyThread()
    t.start()
I'm Thread-1 @ 0
I'm Thread-1 @ 1
I'm Thread-1 @ 2
  • threading.Thread类中的run方法,用于定义线程的功能函数,可以在自己的线程类中进行重写
  • Thread类的start方法执行后,会在线程获得运行资源时调用run方法
  • 如果直接调用run方法,并不能启多线程,而仅仅是一个单线程的程序
课堂练习

实现多线程版的素数计算

import threading

class MyThread(threading.Thread):
    def __init__(self, beg, end):  # 通过类的构造方法进行参数据传递
        super(MyThread, self).__init__()  # 要调用父类的构造方法来进行初始化
        self.__beg = beg
        self.__end = end

    def __isPrime(self, n):  # 可以将某些处理函数变为私有方法
        for x in range(2, n):
            if n % x == 0:
                return False
        else:
            return True

    def run(self):  # 方法名不能改变,只重写
        for n in range(self.__beg, self.__end):
            if self.__isPrime(n):
                print('%s:%d是素数' % (threading.current_thread().name, n))


if __name__ == '__main__':
    t1 = MyThread(3, 1001)
    t2 = MyThread(1001, 2001)
    t3 = MyThread(2001, 3001)

    t1.start()
    t2.start()
    t3.start()

    # t1.run()  # 如果直接调用run方法,并不能启多线程,而仅仅是一个单线程的程序
    # t2.run()
    # t3.run()




- end -

你可能感兴趣的:(进程与线程 -- 多线程)