多线程

多线程

多进程可以同时执行多任务,而也可以通过多线程来完成,一个进程至少有一个线程。

  • Python中提供了threading模块来对多线程的操作

    • 启动方法:就是把一个函数传入并创建Thread实例,然后调用start()开始执行:
    • 上述多进程的有个小例子修改一下:
    #!/usr/bin/env python
    import multiprocessing
    import threading
    import time
        def func(msg):
        print("*******start******{}".format(msg))
        time.sleep(3)
        print("*******end******{}".format(msg))
    if __name__ == '__main__':
        # n = multiprocessing.cpu_count()  # 调用多进程的方法,注释掉
        # pool = multiprocessing.Pool(processes=n)
        for i in range(1,6):
            msg = 'hello,{}'.format(i)
            # pool.apply_async(func,(msg,)) # 多进程方法,注意对比
            t = threading.Thread(target=func,args=(msg,))  实例化一个多线程
            t.start()
        # print("*******start main*********")
        # pool.close()
        # pool.join()
    

    多线程调用方法和多进程:
    t = threading.Thread(target=action, args=(i,))

  • 线程锁Lock

    • 先看一个例子:
    import time, threading
    balance = 0
    def change_it(n):
        global balance
        balance = balance + n
        balance = balance - n
    def run_thread(n):
        for i in range(100000):
            change_it(n)
    t1 = threading.Thread(target=run_thread, args=(5,))
    t2 = threading.Thread(target=run_thread, args=(8,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(balance)
    

    理论上,balance的值为零,但是,由于线程的调度是由操作系统决定的,当t1、t2交替执行时,只要循环次数足够多,balance的结果就不一定是0了。这是由于多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。

    • 如果我们要确保balance计算正确,就要给change_it()上一把锁,当某个线程开始执行change_it()时,我们说,该线程因为获得了锁,因此其他线程不能同时执行change_it(),只能等待,直到锁被释放后,获得该锁以后才能改。由于锁只有一个,无论多少线程,同一时刻最多只有一个线程持有该锁,所以,不会造成修改的冲突。创建一个锁就是通过threading.Lock()来实现:
    import time, threading
    lock = threading.Lock() # 实例化一个lock
    balance = 0
    def change_it(n):
        global balance
        balance = balance + n
        balance = balance - n
    
    def run_thread(n):
        for i in range(1000000):
            lock.acquire() # 获取锁,使其在被调用时其它进程无法调用它
            try:
                change_it(n)
            finally:
                lock.release() # 最后要释放锁
    
    t1 = threading.Thread(target=run_thread, args=(5,))
    t2 = threading.Thread(target=run_thread, args=(8,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(balance)
    
  • 线程池

    • 通过传入一个参数组来实现多线程,并且它的多线程是有序的,顺序与参数组中的参数顺序保持一致。
    • 安装方法:
    pip install threadpool  
    
    • 调用方法:
    pool = ThreadPool(poolsize)  
    requests = makeRequests(some_callable, list_of_args, callback)  
    [pool.putRequest(req) for req in requests]  
    pool.wait() 
    

    第一行定义了一个线程池,表示最多可以创建poolsize这么多线程;
    第二行是调用makeRequests创建了要开启多线程的函数,以及函数相关参数和回调函数,其中回调函数可以不写,default是无,也就是说makeRequests只需要2个参数就可以运行;
    第三行用法是将所有要运行多线程的请求扔进线程池,[pool.putRequest(req) for req in requests]
    第四行是等待所有的线程完成工作后退出。

    • 例子:
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import threadpool
    def hello(m, n, o):
        print "m = %s, n = %s, o = %s" % (m, n, o)
    if __name__ == '__main__':
    # 方法1
        lst_vars_1 = ['1', '2', '3']  
        lst_vars_2 = ['4', '5', '6']
        func_var = [(lst_vars_1, None), (lst_vars_2, None)]
    # 方法2
        dict_vars_1 = {'m': '1', 'n': '2', 'o': '3'}    
        dict_vars_2 = {'m': '4', 'n': '5', 'o': '6'}  
        func_var = [(None, dict_vars_1), (None, dict_vars_2)]
        pool = threadpool.ThreadPool(2)  
        requests = threadpool.makeRequests(hello, func_var)
        [pool.putRequest(req) for req in requests]    
        pool.wait()

转载于:https://my.oschina.net/u/3822958/blog/1817092

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值