Python 的 进程/线程

  • 进程是操作系统分配内存的基本单元,进程之间的内存是相互隔离的,通过icp机制/管道通信。
    一个进程可以划分为多个线程,线程是进程的执行单元 ,也是操作系统分配cpu的执行单元;线程启用的越多,占用cpu越多。

    使用多线程/多进程可以提升执行效率,缩短程序执行时间;改善用户体验。

  • python中使用多进程比多线程更好,因为多进程相互之间是独立的,程序执行效率更高。

进程

from multiprocessing import Process
import subprocess  # subprocess子进程
import time
import os

def output():
    print(os.getpid())  # 启用多进程
    while True:
        print('Pong', end = '', flush=True)  # flush=True关闭缓存
        time.sleep(0.001)
        
def main():
    print(os.getpid)  # 打印进程号
    p = Process(target=output)  # 这里传入函数名,表示进程启用后才在这个进程里面去执行函数
    p.start()
    while True:
        print('Ping', end = '', flush=True)
        time.sleep(0.001)

def main():
    subprocess.call('calc')  # call调用calc计算器
    subprocess.call('notepad')
    
    
if __name__ == '__main__':
    main()

线程

  • 多线程是共享内存的,共享数据。
    python不能用到cpu的多核特性,但是这不代表他的多进程、多线程是无用的。
    实际开发中,多线程的程序不好写,也不好调试,因为cpu分配是随机的,运行时如果有bug那么就不知道它什么时候回出现问题。
  • 创建线程的两种方式:
    1,直接创建Thread对象并通过target参数指定线程启动后要执行的任务。
    2,继承Thread自定义线程,通过重写run方法指定线程启动后执行的任务,推荐使用这种方法!
from threading import Thread  # from thread是python2中使用的模块
from time import sleep

def output():
    while True:
        print('Pong', end='', flush=True)
        sleep(0.001)

def main():
    t1 = Thread(target=output)
    t1.start()
    while True:
        print('Ping', end='', flush=True)
        sleep(0.001)

if __name__ == '__main__':
    main()
from time import sleep

def output(string):
    while True:
        print(string, end='', flush=True)
        sleep(0.001)

def main():
    # 这里应该使用元组,并且尽管只有一个元素,但是也要加上逗号,否则就是一个字符串
    t1 = Thread(target=output, args=('Ping',))
    t1.start()
    t2 = Thread(target=output, args=('Pong',))
    t2.start()

if __name__ == '__main__':
    main()
from threading import Thread
from time import sleep

def output(string):
    while True:
        print(string, end='', flush=True)
        sleep(0.001)

def main():
    # daemon=True - 将线程设置为守护线程(不值得保留的线程),其他线程/主程序如果执行完了,那么守护线程自动结束
    t1 = Thread(target=output, args=('Ping',),daemon=True)
    t1.start()
    t2 = Thread(target=output, args=('Pong',), daemon=True)
    t2.start()

if __name__ == '__main__':
    main()

多进程模拟下载文件
如果多个任务之间没有任何的关联(独立子任务),而且希望利用cpu的多核特性,那么我们推荐使用多进程,因为任务之间没有数据交换

import time
import random
from threading import Thread


def download(filename):
    print('开始下载%s...' % filename)
    delay = random.randint(5,15)
    time.sleep(delay)
    print('%s下载完成,用时%d秒' % (filename, delay))

# 如果要写多线程,推荐使用这种方法
class DownloadTask(Thread):

    def __init__(self, filename):
        super().__init__()
        self._filename = filename

    # 钩子函数(hook) / 回调函数(callback)(写了这个方法,但是从来没有调用它,它是让系统启动线程的时候自动回调这个方法)
    # 写程序时启用线程用start,不能用run!!!
    def run(self):
        download(self._filename)

def main():
    start = time.time()
    t1 = DownloadTask('Python从入门到住院.pdf')
    t1.start()
    t2 = DownloadTask('Pekin Hot.avi')
    t2.start()
    t1.join()  # join等待进程结束(然后再打印时间)
    t2.join()
    end = time.time()
    print('总共耗费了%f秒' % (end - start))


if __name__ == '__main__':
    main()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章