码迷,mamicode.com
首页 > 其他好文 > 详细

Threading module

时间:2017-10-16 19:38:02      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:init   __init__   线程变量   返回   bre   超时   共享   art   event   

1. 基本方法  

技术分享
from threading import Thread
import time
def sayhi(name):
    time.sleep(2)
    print(%s say hello %name)

if __name__ == __main__:
    t=Thread(target=sayhi,args=(egon,))
    t.start()
方法1
技术分享
from threading import Thread
import time
class Sayhi(Thread):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        time.sleep(2)
        print(%s say hello % self.name)


if __name__ == __main__:
    t = Sayhi(egon)
    t.start()
方法2

 

2.与进程的区别

  进程             线程

      开启慢———开启快  

     不共享内存 — 共享内存

     进程编号不同——进程编好相同

 

3. 相关方法

Thread实例对象的方法
  isAlive(): 返回线程是否活动的。
  getName(): 返回线程名。
  setName(): 设置线程名。

threading模块提供的一些方法:
 可以采用from threading import currentThread,enumerate,activeCount
  threading.currentThread(): 返回当前的线程变量。
  threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
通常用 currentThread().getName()拿到线程名

 

4. 守护线程

  thread_obj.daemon = True

  thread_obj.setDaemon(True)

 

5. 锁

5.1. Cpython Global Interpreter Lock

GIL导致同一时间一个进程只能有一个线程在执行。GIL的本质是线程在争夺python解释器的执行权限。

5.2 互斥锁

  GIL锁并不影响脚本代码。为了防止在修改公有数据出现错误,需要加互斥锁

技术分享
lock = Lock()
lock.acquire()    #与multiprocess不同的是 不需要传入lock 只需要在func中直接添加
code...
lock.release()

#支持with statement
with lock:
    code...
方法

  互斥锁与join的区别:join实现串行,本质是限制并发的发起权限。互斥锁是多子线程/子进程发起后,争夺子程序部分代码的执行权限。lock的效率更高

5.3 死锁

在锁嵌套过程中,两个程序各持有一把锁,并争夺另一把锁。

技术分享
 1 from threading import Thread,Lock
 2 import time
 3 mutexA=Lock()
 4 mutexB=Lock()
 5 
 6 class MyThread(Thread):
 7     def run(self):
 8         self.func1()
 9         self.func2()
10     def func1(self):
11         mutexA.acquire()
12         print(\033[41m%s 拿到A锁\033[0m %self.name)
13 
14         mutexB.acquire()
15         print(\033[42m%s 拿到B锁\033[0m %self.name)
16         mutexB.release()
17 
18         mutexA.release()
19 
20     def func2(self):
21         mutexB.acquire()
22         print(\033[43m%s 拿到B锁\033[0m %self.name)
23         time.sleep(2)
24 
25         mutexA.acquire()
26         print(\033[44m%s 拿到A锁\033[0m %self.name)
27         mutexA.release()
28 
29         mutexB.release()
30 
31 if __name__ == __main__:
32     for i in range(10):
33         t=MyThread()
34         t.start()
35 
36 ‘‘‘
37 Thread-1 拿到A锁
38 Thread-1 拿到B锁
39 Thread-1 拿到B锁
40 Thread-2 拿到A锁
41 然后就卡住,死锁了
42 ‘‘‘
死锁举例

解决方法:

mutexA=mutexB=threading.RLock() 

#一个线程拿到锁,counter加1,该线程内又碰到加锁的情况,则counter继续加1,这期间所有其他线程都只能等待,等待该线程释放所有锁,即counter递减到0为止

 

6.Semaphore

  和pool的区别是,pool是抢进程创建,Semaphore是进程创建后的抢运行权限。相当于有多个钥匙的锁

  

from threading import Thread,Semaphore
import threading
import time
# def func():
#     if sm.acquire():
#         print (threading.currentThread().getName() + ‘ get semaphore‘)
#         time.sleep(2)
#         sm.release()
def func():
    sm.acquire()
    print(%s get sm %threading.current_thread().getName())
    time.sleep(3)
    sm.release()
if __name__ == __main__:
    sm=Semaphore(5)
    for i in range(23):
        t=Thread(target=func)
        t.start()

 

7. Event

event.isSet():返回event的状态值;

event.wait(timeout=second):如果 event.isSet()==False将阻塞线程; timeout是等待时间

event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;

event.clear():恢复event的状态值为False。
技术分享
from threading import Thread,Event
import threading
import time,random
def conn_mysql():
    count=1
    while not event.is_set():
        if count > 3:
            raise TimeoutError(链接超时)
        print(<%s>第%s次尝试链接 % (threading.current_thread().getName(), count))
        event.wait(0.5)
        count+=1
    print(<%s>链接成功 %threading.current_thread().getName())


def check_mysql():
    print(\033[45m[%s]正在检查mysql\033[0m % threading.current_thread().getName())
    time.sleep(random.randint(2,4))
    event.set()
if __name__ == __main__:
    event=Event()
    conn1=Thread(target=conn_mysql)
    conn2=Thread(target=conn_mysql)
    check=Thread(target=check_mysql)

    conn1.start()
    conn2.start()
    check.start()
用法

 

8. Queue

import queue
q=queue.Queue() q.put(first) q.put(second) q.put(third) print(q.get()) print(q.get()) print(q.get())

queue.LifoQueue() 先进后出

queue.PriorityQueue()  >>> q.put((30,‘c‘))  前面的数字越小越重要,大小相同的情况下比较后面的大小

 

 

9. timer

from threading import Timer
 
 
def hello():
    print("hello, world")
 
t = Timer(1, hello)
t.start()  # after 1 seconds, "hello, world" will be printed

 

 

10.Condition

import threading


def run(n):
    con.acquire()
    con.wait()
    print("run the thread: %s" % n)
    con.release()


if __name__ == __main__:

    con = threading.Condition()
    for i in range(10):
        t = threading.Thread(target=run, args=(i,))
        t.start()

    while True:
        inp = input(>>>)
        if inp == q:
            break
        con.acquire()
        con.notify(int())inp
        con.release()

 

Threading module

标签:init   __init__   线程变量   返回   bre   超时   共享   art   event   

原文地址:http://www.cnblogs.com/yxi-liu/p/7677889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!