zoukankan      html  css  js  c++  java
  • 多线程的使用

    1,一个cpu一次只能执行一个任务, 多个cpu同时可以执行多个任务
    2,一个cpu一次只能执行一个进程, 其他进程处于非运行状态
    3,进程里包含的执行单元叫线程,一个进程可以包含多个线程
    4,一个进程的内存空间是共享的,每个进程里的线程都可以使用这个共享空间
    5,一个线程在使用这个共享空间的时候, 其它的线程必须等待(阻塞状态)
    6,互斥锁作用就是防止多个线程同时使用这块内存空间, 先使用的线程会将空间上锁, 其它的线程处于等待状态, 等锁开了才能进
    7,进程: 表示程序的一次执行
    8,线程:CPU运算的基本调度单位
    9,GIL(全局锁):Python里的执行通行证, 而且只有一个, 拿到通行证的线程就可以进入CPU执行任务, 没有GIL的线程就不能执行任务
    10, Python的多线程适用于大量密集的I/O处理
    11,Python的多进程适用于大量的密集并行计算
    
    添加线程
    threading.Thread(target, args)
    使用threading.Thread()新建一个线程, target是需要执行的函数, args是需要传入该函数的参数, args接受一个tuple, 即使只有一个参数 也需要写成(x,)形式
    import threading
    
    def thread_job():
        print('1111')
    
    def main():
        thread = threading.Thread(target=thread_job,) # 添加一个线程
        thread.start()  # 开始该线程
    
    
    if __name__ == '__main__':
        main()
    
    线程阻塞:join
    join()的作用是调用该线程时, 等待该线程完成之后在继续往下执行
    join通常用于主线程与子线程之间, 主线程等待子线程运行完毕后在继续执行, 避免子程序和主程序同时执行, 子程序还没有运行完的时候就已经运行结束
    import threading
    import time
    
    def T1_job():
        print('T1 start
    ')
        for i in range(10):
            time.sleep(10)
        print('T1 finish
    ')
    
    
    def T2_job():
        print('T2 start
    ')
        print('T2 finish
    ')
    
    
    def main():
        thread1 = threading.Thread(target=T1_job, name='T1')  
        thread2 = threading.Thread(target=T2_job, name='T2')  
        thread1.start()
        thread1.join()  # 等待执行thread1完成后才能进行下一步-主程序
        thread2.start()
        thread2.join()
        print('all done')
    
    
    if __name__ == '__main__':
        main()
    
    Queue(队列对象)
    Queue是Python中的标准库, 可以直接import Queue引用, 队列是线程间最常用的交换数据的形式
    Python下多线程的思考
    对于资源, 加锁是个重要的环节, 因为Python原生的list ,dict等, 都是 not thread safe的, 而Queue,是线程安全的, 因此在满足使用条件下, 建议使用队列
    1, 初始化: class.Queue.Queue(maxsize) FIFO先进先出
    2, 包中国的常用方法:
    Queue.qsize()返回队列的大小
    Queue.empty()如果队列为空, 返回True,反之False
    Queue.full()如果队列满了, 返回True,反之False
    Queue.full与maxsize大小对应
    Queue.get([block[, timeout]])获取队列, timeout等待时间
    3, 创建一个"队列"对象
    import Queue
    myqueue = Queue.Queue(maxsize=10)
    4,将一个值放入队列中
    myqueue.put(10)
    5,将一个值从队列中取出
    myqueue.get()


    import threading
    from queue import Queue

    """
    # Queue是python标准库中的线程安全的队列(FIFO)实现, 提供了一个适用于多线程编程的先进先出的数据结构,即队列.
    # Queue是一种先进先出的数据结构, 一般来说读数据都从Queue头读, 写数据都从Queue尾写入
    # """

    def job(l,q):
    for i in range(len(l)):
    l[i] = l[i] ** 2
    q.put(l) # 线程中, return获取的值无法提取, 需要放入q中

    def multithreading():
    q = Queue() # 队列
    threads = [] # 全部线程
    data = [[1, 2, 3], [3, 4, 5], [4, 4, 4], [5, 5, 5]]
    for i in range(4):
    t = threading.Thread(target=job, args=(data[i], q)) # 4个线程来执行job函数
    t.start()
    threads.append(t) # 当前线程加入全部线程中

    # 对主线程的每一个线程都执行join()
    for thread in threads:
    thread.join()

    results = [] # 保存结果
    for _ in range(4):
    results.append(q.get()) # 从q中取值, 每次只能按顺序拿出一个值
    print(results)

    if __name__ == '__main__':
    multithreading()


    """
    线程锁:Lock
    lock在不同线程使用同一共享内存时, 能够确保线程之间互不影响
    使用lock的方法是: 在每个线程执行运算修改共享内存之前执行lock.acquire()将共享内存上锁, 确保当前线程执行时, 内存不会被其他线程访问; 执行运算完毕后使用lock.release() 将锁关闭, 保证其他的线程可以使用该共享内存. lock.acquire()和lock.release()必须成对出现
    下面代码 将lock.acquire(), lock.release()注释掉后, 输出结果是混乱的, 加锁后, 输出结果按顺序执行
    
    # """
    
    def job1():
        global A, lock
        lock.acquire()  # 打开锁
        for i in range(10):
            A += 1
            time.sleep(2)
            print('job1', A)
        lock.release()  # 关闭锁
    
    def job2():
        global A, lock
        lock.acquire()  # 打开锁
        for i in range(10):
            A += 10
            time.sleep(2)
            print('job2', A)
        lock.release()  # 关闭锁
    
    if __name__ == '__main__':
        lock = threading.Lock()  # lock锁
        A = 0
        t1 = threading.Thread(target=job1)
        t2 = threading.Thread(target=job2)
        t1.start()
        t2.start()
    
    import threading
    from multiprocessing.dummy import Pool as ThreadPool
    
    """
    线程池有几种方法可以实现, 这里我们使用multiprocessing.dummy库
    """
    def job(i):
        print(i, '
    ', threading.current_thread())
    
    if __name__ == '__main__':
        pool = ThreadPool(4)  # 创建一个包含4个线程的线程池
        pool.map(job, range(12))
        pool.close()  # 关闭线程池的写入
        pool.join()  # 阻塞, 保证子线程运行完毕后在继续主进程
    
  • 相关阅读:
    C++头文件保护符和变量的声明定义
    ReactNavtive框架教程(2)
    扩展方法使用
    华为0基础——(练习用)挑7
    HTTP Status 500
    屏蔽DataGridView控件DataError 事件提示的异常信息
    POJ 3630 Phone List Trie题解
    【学习总结】数学-向量叉积
    9.1-9.30推荐文章汇总
    Autolayout环境设置任意个数相等间距排列的按钮的方法
  • 原文地址:https://www.cnblogs.com/wangyue0925/p/11251155.html
Copyright © 2011-2022 走看看