python 多线程的一点东西

1,Thread Local类的用法     

     python 中多线程的并发跟其他语言一样,需要考虑多线程并发访问去全局变量所带来的问题,python的local类解决了这个问题,通过它让每个线程内部有一个相对独立的local保存数据,某一个线程修改了数据,不影响其他线程中保存的数据。

 1 from threading import Thread
 2 import threading
 3 import time
 4 local_value=threading.local()
 5 local_value.x='en'
 6 class threadtest(Thread):
 7 
 8      def __init__(self,num):
 9          Thread.__init__(self)
10          self.num=num
11          
12      def run(self):
13          local_value.x=self.getName()
14          for i in range(self.num):
15              time.sleep(1)
16              print(local_value)
17          
18 
19 threadtest(3).start()
20 threadtest(2).start()        

执行结果是:

Thread-1
Thread-2
Thread-1
Thread-2
Thread-1
[Finished in 3.2s]

这表明,虽然两个线程公用一个local_value.x但是确实相互独立的变量。

另外,

local_value.x=self.getName()放在__init__()中时,运行会报错,说'_thread._local' object has no attribute 'x',目测是因为在初始化__init__的时候,线程还没有建立local_value对象,只有在__init__执行完之后,才可以开始赋值(不过对于这一点我不确定,看源码也看晕了)。

2,Thread join()方法的用法及含义:

join()源码中的解释:

  """Wait until the thread terminates.

        This blocks the calling thread until the thread whose join() method is
        called terminates -- either normally or through an unhandled exception
        or until the optional timeout occurs.

        When the timeout argument is present and not None, it should be a
        floating point number specifying a timeout for the operation in seconds
        (or fractions thereof). As join() always returns None, you must call
        isAlive() after join() to decide whether a timeout happened -- if the
        thread is still alive, the join() call timed out.

        When the timeout argument is not present or None, the operation will
        block until the thread terminates.

        A thread can be join()ed many times.

        join() raises a RuntimeError if an attempt is made to join the current
        thread as that would cause a deadlock. It is also an error to join() a
        thread before it has been started and attempts to do so raises the same
        exception.

        """

当某个子线程调用join()时,主线程将阻塞,直至该线程执行完毕,

当每个子线程调用都join(),且不设置参数时

from threading import Thread
import threading
import time
local_value=threading.local()
class threadtest(Thread):
    
     def __init__(self,num):
         Thread.__init__(self)
         self.num=num
         #local_value.x=self.getName()
     def run(self):
         local_value.x=self.getName()
         for i in range(self.num):
             time.sleep(1)
             print(local_value.x)
from threading import current_thread
        
#print(current_thread(),local_value.__dict__,'--')
a=threadtest(2)
b=threadtest(2)
c=threadtest(2)
a.start()
a.join()
b.start()
b.join()        
c.start()
c.join()
for i in range(2):
    time.sleep(1)
    print(current_thread())

结果是:

Thread-1
Thread-1
Thread-2
Thread-2
Thread-3
Thread-3
<_MainThread(MainThread, started 6688)>
<_MainThread(MainThread, started 6688)>
[Finished in 8.2s]

即:哪个子线程先调用join,就先完成它的任务,依次执行,不仅是主线程,其他的子线程也必须为调用了join的线程让路,让它执行完毕,在执行下一个调用了join的子线程,最后才轮到主线程上台(主线程:卧槽,我才是老大啊!)

 

如果每个子线程都设置时间参数,但是时间参数小于完成任务所需的时间的话

from threading import Thread
import threading
import time
local_value=threading.local()
class threadtest(Thread):
    
     def __init__(self,num):
         Thread.__init__(self)
         self.num=num
         #local_value.x=self.getName()
     def run(self):
         local_value.x=self.getName()
         for i in range(self.num):
             time.sleep(1)
             print(local_value.x)
from threading import current_thread
        
#print(current_thread(),local_value.__dict__,'--')
a=threadtest(6)
b=threadtest(6)
#c=threadtest(6)
a.start()
b.start()
a.join(2)
b.join(2)
#c.start()
#c.join(2)
#以下是主线程
for i in range(2):
    #ime.sleep(1)
    print(current_thread())

 

结果为:

Thread-1
Thread-2
Thread-1
Thread-2
Thread-1
Thread-2
Thread-1
Thread-2
<_MainThread(MainThread, started 8652)>
<_MainThread(MainThread, started 8652)>
Thread-1
Thread-2
Thread-1
Thread-2
[Finished in 6.2s]

从结果可以看出,子线程开始确实阻塞了主线程,但是没有阻塞其他子线程,所以两个子线程仍然是并行执行,一共阻塞了4秒钟(线程1,和线程2一起),四秒钟后程序开始执行join之后的代码,也就是主线程的代码,从这之后,主线程和子线程之间是并行关系。

 

总结一下(不要告诉我你只看总结)

1,子线程只要调用了join函数,就会阻塞主线程,不管有没有设置参数,

2,子线程如果调用join函数,设置了时间参数,主线程在设置的时间内被阻塞,子线之间一直是并行的,时间到了后,程序将会执行join()之后的代码。

3,如果子线程调用join函数,没有设置时间参数,那么子线程之间不会并行,而是有优先成那个调用了join的子线程。

如果不调用join,那么主线程不会为子线程阻塞,所有线程并发执行。

转载于:https://www.cnblogs.com/ladingwu/p/4632787.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值