Python学习

Python--多线程

2018-03-29  本文已影响181人  JM68

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

1、使用线程可以把占据长时间的程序中的任务放到后台去处理。

2、用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度程序的运行速度可能加快

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

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

每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。

指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。

线程可以被抢占(中断)。在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) -- 这就是线程的退让。

Python中使用线程有两种方式:函数或者用类来包装线程对象。

下面我以两个简单的示例来解释这两种方式:

模拟用多线程下载文件,用的是函数的方法:

from random import randint
from threading import Thread
from time import time, sleep


def download(filename):
    print('开始下载%s...' % filename)
    time_to_download = randint(5, 10)
    sleep(time_to_download)
    print('%s下载完成! 用时%d秒' % (filename, time_to_download))


def main():
    start = time()  # 开始的时间点
    t1 = Thread(target=download, args=('A文件',))   # 注意字符串后面的逗号,表示传入的是元组   
    t1.start()      # 启动下载A文件的线程
    t2 = Thread(target=download, args=('B文件',))
    t2.start()
    t1.join()      # 等待执行结束
    t2.join()      # 等待执行结束
    end = time()    # 结束的时间点
    print('总共耗费了%.5f秒' % (end - start))


if __name__ == '__main__':
    main()

用多线程写的赛车动画,五个线程控制五辆由色块表示的小车移动,这样小车可以同时移动,而不是一辆一辆依次移动

import pygame
from random import uniform, randint
from threading import Thread


class Car(object):

    def __init__(self, x, y):
        self._color = [randint(0, 255), randint(0, 255), randint(0, 255)]
        self._x = x
        self._y = y

    @property
    def x(self):
        return self._x

    def move(self):
        self._x += uniform(0.5, 3)

    def head(self):
        return self._x + 20

    def draw(self, screen):
        pygame.draw.rect(screen, self._color, (self._x, self._y, 20, 20), 0)

    def run(self, screen):
        self.move()
        self.draw(screen)


class Mythread(Thread):
    def __init__(self, car, screen):
        super().__init__()
        self._car = car
        self._screen = screen

    def run(self):
        Car.move(self._car)
        Car.draw(self._car, self._screen)


def main():
    pygame.init()

    screen = pygame.display.set_mode([600, 500])
    pygame.display.set_caption('赛车游戏')
    screen.fill([255, 255, 255])
    pygame.draw.line(screen, [0, 0, 0], (37, 0), (37, 500), 5)
    pygame.draw.line(screen, [255, 0, 0], (580, 0), (580, 500), 5)
    cars = []
    for i in range(5):
        car = Car(20, 50+100*i)
        cars.append(car)
    for car in cars:
        car.draw(screen)
    pygame.display.flip()
    running = True
    gameover = False

    def game_over(c1):
        nonlocal gameover
        if c1.head() > 580:
            gameover = True

    def refresh():
        screen.fill((255, 255, 255))
        pygame.draw.line(screen, [0, 0, 0], (37, 0), (37, 500), 5)
        pygame.draw.line(screen, [255, 0, 0], (580, 0), (580, 500), 5)
        for _ in cars:
            Mythread(_, screen).start()
        pygame.display.flip()
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                while not gameover:
                    for car in cars:
                        game_over(car)
                    refresh()
            pygame.display.flip()

    pygame.quit()


if __name__ == '__main__':
    main()

上一篇 下一篇

猜你喜欢

热点阅读