python学习04多线程

1、线程与进程基本概念
2、同步与异步
3、并发与并行
当用户在操作系统中启动某一个程序中,启动了至少一个进程,程序是一种静态资源实体,只是一系列代码。
进程是动态的,当操作系统将程序数据载入内存时,创建一个动态实体,对各种资源进行操作。

程序(静态) + 数据集 = 进程(运行时)
不同进程之间不共享内存,一个进程包含至少一个或多个线程
多个线程之间共享一个进程的内存,没有控制好,容易出现竞争状态,为了避免这种状态,出现互斥锁、信号量等机制

互斥锁是指一个线程使用某一内存空间会获得的一把锁,使用锁将内存空间锁起来,其他线程只有等当前线程使用完毕并将锁
释放,才能使用该内存空间中的资源。
信号量用来指定某一内存空间通常可以被多少个线程使用。如当信号量为4时,内存空间中最多能同时存在4个线程,某个线程操作完
内存空间中的资源后,信号量会自增1,允许其他线程进入到该内存空间

同步与异步

同步是指不同程序单元为了完成某个任务通过某种方式协调一致,异步是指不需要协调也可独立完成。

‘’’
并发是指有限物理资源尽可能处理多个任务
‘’’

from flask import Flask
import time
app = Flask(__name__)
def longtime(s):
    time.sleep(s)

@app.route('/index')

def index():
    longtime(10)
    return 'hello sync flask'
if __name__ == '__main__':
    app.run()

#通过性能池实现

import time
from concurrent.futures import ThreadPoolExecutor
from flask import Flask
executor = ThreadPoolExecutor(2)#创建线程池大小为2
app = Flask(__name__)
def longtime(s):
    time.sleep(s)
@app.route('/index')
def index():
    executor.submit(longtime,10)
    return 'hello async flask'

if __name__ == '__main__':
    app.run()

‘’’
在python中有三种使用线程的方式,分别是thread、threading、ThreadPoolExecutor
threading 有两种方式创建线程
1、创建threading.Thread实例,将需要被线程执行的函数传入该实例
2、创建一个类,继承于threading.Thread,重写run方法
‘’’

import time
import threading

def longTime(s):
    time.sleep(s)

def main():
    t = threading.Thread(target=longTime,args=[10])
    t.start()#start用于启动线程,在同一个线程中不能被多次调用
    t.join()#将主线程挂起,直到子线程运行结束
    print('Done')#子线程会执行10s,Done在10s后才打印

if __name__ == '__main__':
    main()

import time
import threading

class MyThread(threading.Thread):
    def __init__(self,func,args,tname = ''):
        #super (MyThread,self).__init__()
        super().__init__()
        self.tname = tname
        self.func = func
        self.args = args

    def run(self):
        self.func(*self.args)

def longtime(s):
    time.sleep(s)

def main():
    t = MyThread(longtime,(10,),longtime.__name__)
    t.start()
    t.join()

if __name__ == '__main__':
    main()

#ThreadPoolExecutor使用
#相比threading等模块,该模块通过submit返回一个future对象,通过它主线程(进程)中可以获取某一个
#线程(进程)执行的状态或者某一任务执行的状态及返回值

import time
import random
from concurrent.futures import ThreadPoolExecutor,as_completed
def spider(url):
    '''
    爬虫方法
    :param url:
    :return:
    '''
    time.sleep(random.randint(1,5))
    print(f'crawl task {url} finished')
    return url

#创建一个最大容纳数量为5的线程池
with ThreadPoolExecutor(max_workers=5) as executor:
    urls = ['https://abc.com','https://efg.com','https://hij.com','https://klm.com'
            ,'https://nop.com','https://rsz.com']
    all_task = []
    for url in urls:#将任务提交到线程池
        task = executor.submit(spider,url)
        #将任务添加到对象列表
        all_task.append(task)
    #阻塞,获得任务完成后的返回值
    for future in as_completed(all_task):
        result = future.result()
        print(f'result:{result}')
    print('main_finished')
'''

as_completed()方法是一个生成器,在没有完成任务的时候,会一直阻塞,除非设置了timeout
当有某个任务完成的时候,会yield这个任务,就能执行for循环下的语句,然后继续阻塞,循环到所有的任务结束
同时,先完成的任务会返回给主线程
‘’’

你可能感兴趣的:(python学习,python,学习)