zoukankan      html  css  js  c++  java
  • 【python,threading】python多线程

    使用多线程的方式

    1、  函数式:使用threading模块threading.Thread(e.g target name parameters)

     1 import time,threading
     2 def loop():
     3     print("thread %s is running..." % threading.current_thread().name) 
     4     n = 0
     5     while n < 5:
     6         n += 1
     7         print("thread %s is running... n = %s" % (threading.current_thread().name,str(n))) 
     8         time.sleep(1)
     9     print("thread %s is over..." % threading.current_thread().name) 
    10     
    11 print("thread %s is running..." % threading.current_thread().name) 
    12 
    13 ts = []
    14 for i in range(5):
    15     t = threading.Thread(target = loop, name = 'loopThread '+ str(i))
    16     t.start()
    17     ts.append(t)
    18 for t in ts:
    19     t.join()
    20 print("thread %s is over..." % threading.current_thread().name) 

    多线程的输出:

    thread MainThread is running...
    thread loopThread 0 is running...
    thread loopThread 0 is running... n = 1
    thread loopThread 1 is running...
    thread loopThread 1 is running... n = 1
    thread loopThread 2 is running...
    thread loopThread 2 is running... n = 1
    thread loopThread 0 is running... n = 2
    thread loopThread 1 is running... n = 2
    thread loopThread 2 is running... n = 2
    thread loopThread 0 is running... n = 3
    thread loopThread 1 is running... n = 3
    thread loopThread 2 is running... n = 3
    thread loopThread 0 is running... n = 4
    thread loopThread 1 is running... n = 4
    thread loopThread 2 is running... n = 4
    thread loopThread 0 is running... n = 5
    thread loopThread 1 is running... n = 5
    thread loopThread 2 is running... n = 5
    thread loopThread 0 is over...
    thread loopThread 1 is over...
    thread loopThread 2 is over...
    thread MainThread is over...

    python中得thread的一些机制和C/C++不同:在C/C++中,主线程结束后,其子线程会默认被主线程kill掉。而在python中,主线程结束后,会默认等待子线程结束后,主线程才退出。

    python对于thread的管理中有两个函数:join和setDaemon

    join:如在一个线程B中调用threada.join(),则threada结束后,线程B才会接着threada.join()往后运行。

    setDaemon:主线程A启动了子线程B,调用b.setDaemaon(True),则主线程结束时,会把子线程B也杀死。【此段内容摘录自junshao90的博客

    2. 使用面向对象方式。创建子类继承自threading.Thread,需overwrite run方法

     1 import time,threading
     2 class threadTest(threading.Thread):    
     3     def __init__(self,tname):
     4         threading.Thread.__init__(self)
     5         self.name = tname    
     6     def run(self):
     7         print("thread %s is running..." % threading.current_thread().name) 
     8         n = 0
     9         while n < 5:
    10             n += 1
    11             print("thread %s is running... n = %s" % (threading.current_thread().name,str(n))) 
    12             time.sleep(1)
    13         print("thread %s is over..." % threading.current_thread().name)         
    14 print("thread %s is running..." % threading.current_thread().name)   
    15 
    16 for i in range(3):
    17     t = threadTest('t' + str(i))
    18     t.start()
    19     t.join()
    20 print("thread %s is over..." % threading.current_thread().name) 

    运行输出:

    thread MainThread is running...
    thread t0 is running...
    thread t0 is running... n = 1
    thread t0 is running... n = 2
    thread t0 is running... n = 3
    thread t0 is running... n = 4
    thread t0 is running... n = 5
    thread t0 is over...
    thread t1 is running...
    thread t1 is running... n = 1
    thread t1 is running... n = 2
    thread t1 is running... n = 3
    thread t1 is running... n = 4
    thread t1 is running... n = 5
    thread t1 is over...
    thread t2 is running...
    thread t2 is running... n = 1
    thread t2 is running... n = 2
    thread t2 is running... n = 3
    thread t2 is running... n = 4
    thread t2 is running... n = 5
    thread t2 is over...
    thread MainThread is over...

    3. lock

     多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响。

     而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把  内容给改乱了。

    lock 对象:

    acquire():负责取得一个锁。如果没有线程正持有锁,acquire方法会立刻得到锁。否则,它闲意态等锁被释放。一旦acquire()返回,调用它的线程就持有锁。

    release(): 释放锁。如果有其他线程正等待这个锁(通过acquire()),当release()被效用的时候,它们中的一个线程就会

    被唤醒

    以下内容摘自“廖雪峰的官方网站”

    balance为共享资源,多进程同时执行,一定概率结果为balance != 0[详细描述见原文]
    def change_it(n):
        # 先存后取,结果应该为0:
        global balance
        balance = balance + n
        balance = balance - n

    使用threading.Lock()

    import threading
    
    total = 0
    lock = threading.Lock()
    def change(n):
        global total
        total += n
        total -= n
    
    def run_thread(n):
        lock.acquire()
        for i in range(100000):
            change(n)
        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(total)

     4. 其他详细关于对进程的资料可参考

     解决共享资源问题的:条件变量,同步队列

     Vamei的博客Python标准库08 多线程与同步 (threading包)

     片片灵感的博客Python多线程学习

  • 相关阅读:
    memcached客户端memadmin安装使用
    git之一: 在windows下安装git和使用总结
    nginx常用命令
    mysql授权 REVOKE 添加用户等
    mysql密码忘记解决
    个人常用alias
    解决zabbix图形界面中文乱码
    JsonPath的使用
    Httpclient 支持https(转)
    字符串拼接‘+’实现
  • 原文地址:https://www.cnblogs.com/AlexBai326/p/4128640.html
Copyright © 2011-2022 走看看