python-多线程

  ● 先执行最基本的串行执行,从开始到结束可以看到task1先执行,然后是task2,再然后main函数执行结束,总共耗时10s


#coding = utf-8
from time import ctime,time,sleep
def task1(num):
        for i in range(num):
                print ('Func1 Task --- No.%d start at\t%s' %(i,ctime(time())))
                sleep(3)


def task2(num):
        for i in range(num):
                print ('Func2 Task --- No.%d start at\t%s' % (i, ctime(time())))
                sleep(2)


if __name__ == '__main__':
        task1(2)
        task2(2)
        print ('Main Function End %s' % ctime())
  ● 打印结果
  ● root@root2:~/file_xlwu/f1/tmp# python threading_test.py
Func1 Task --- No.0 start at    Sat Aug 13 19:51:08 2016
Func1 Task --- No.1 start at    Sat Aug 13 19:51:11 2016
Func2 Task --- No.0 start at    Sat Aug 13 19:51:14 2016
Func2 Task --- No.1 start at    Sat Aug 13 19:51:16 2016
Main Function End Sat Aug 13 19:51:18 2016


  ● 进阶版 
引入threading.Thread,用两个线程进行程序执行
#coding = utf-8
import threading
from time import ctime,time,sleep
def task1(num):
        for i in range(num):
                print ('Func1 Task --- No.%d start at\t%s' %(i,ctime(time())))
                sleep(3)


def task2(num):
        for i in range(num):
                print ('Func2 Task --- No.%d start at\t%s' % (i, ctime(time())))
                sleep(2)


if __name__ == '__main__':
        t1 = threading.Thread(target = task1, args = (2,))
        t2 = threading.Thread(target = task2, args = (2,))
        t1.start()
        t2.start()
        print ('Main Function End\t %s' % ctime())
执行结果
root@root2:~/file_xlwu/f1/tmp# python threading_test.py
Func1 Task --- No.0 start at    Sat Aug 13 20:36:49 2016
Func2 Task --- No.0 start at    Sat Aug 13 20:36:49 2016
Main Function End       Sat Aug 13 20:36:49 2016
Func2 Task --- No.1 start at    Sat Aug 13 20:36:51 2016
Func1 Task --- No.1 start at    Sat Aug 13 20:36:52 2016
  ● 接下来观察一下daemon参数起什么作用 
设置线程进行setDaemon()操作,讲daemon参数设置为True如下,观察结果:
#coding = utf-8
import threading
from time import ctime,time,sleep
def task1(num):
        for i in range(num):
                print ('Func1 Task --- No.%d start at\t%s' %(i,ctime(time())))
                sleep(3)


def task2(num):
        for i in range(num):
                print ('Func2 Task --- No.%d start at\t%s' % (i, ctime(time())))
                sleep(2)


if __name__ == '__main__':
        t1 = threading.Thread(target = task1, args = (2,))
        t2 = threading.Thread(target = task2, args = (2,))
        t1.setDaemon(True)
        t2.setDaemon(True)


        t1.start()
        t2.start()
        print ('Main Function End\t %s' % ctime())
这里需要注意的是,threading.Thread设置daemon参数必须在start()之前,不然程序会被无限挂起
root@root2:~/file_xlwu/f1/tmp# python threading_test.py
Func1 Task --- No.0 start at    Sat Aug 13 20:45:20 2016
Main Function End       Sat Aug 13 20:45:20 2016
Func2 Task --- No.0 start at   Sat Aug 13 20:45:20 2016
由此可见,t.setDaemon(True)的结果是:主线程在线程t结束之前就会随着主线程的结束而kill掉线程t,程序结束。
  ● 再玩一次:
#coding = utf-8
import threading
from time import ctime,time,sleep
def task1(num):
        for i in range(num):
                print ('Func1 Task --- No.%d start at\t%s' %(i,ctime(time())))
                sleep(3)


def task2(num):
        for i in range(num):
                print ('Func2 Task --- No.%d start at\t%s' % (i, ctime(time())))
                sleep(5)


if __name__ == '__main__':
        t1 = threading.Thread(target = task1, args = (2,))
        t2 = threading.Thread(target = task2, args = (2,))
        t1.setDaemon(False)
        t2.setDaemon(True)


        t1.start()
        t2.start()
        print ('Main Function End\t %s' % ctime())
  ● 那这样的话我就搞不懂了,为什么task2的第二条语句还是能打印出来?很令人费解…… 
由此推测setDaemon的作用是针对主线程的,用来设置主线程在执行完之后不能直接退出程序。
root@root2:~/file_xlwu/f1/tmp# python threading_test.py
Func1 Task --- No.0 start at    Sat Aug 13 21:03:57 2016
Func2 Task --- No.0 start at    Sat Aug 13 21:03:57 2016
Main Function End       Sat Aug 13 21:03:57 2016
Func1 Task --- No.1 start at    Sat Aug 13 21:04:00 2016
Func2 Task --- No.1 start at    Sat Aug 13 21:04:02 2016
通过以上执行结果,我们得知Python默认的daemon参数是False的,主线程会等到子线程执行完毕之后才会杀掉子线程结束程序。
  ● 故意将setDaemon放到start后面进行观察
#coding = utf-8
import threading
from time import ctime,time,sleep
def task1(num):
        for i in range(num):
                print ('Func1 Task --- No.%d start at\t%s' %(i,ctime(time())))
                sleep(3)


def task2(num):
        for i in range(num):
                print ('Func2 Task --- No.%d start at\t%s' % (i, ctime(time())))
                sleep(2)


if __name__ == '__main__':
        t1 = threading.Thread(target = task1, args = (2,))
        t2 = threading.Thread(target = task2, args = (2,))


        t1.start()
        t2.start()
        t1.setDaemon(False)
        t2.setDaemon(True)


        print ('Main Function End\t %s' % ctime())


执行结果如下:
root@root2:~/file_xlwu/f1/tmp# python threading_test.py
Func1 Task --- No.0 start at    Sat Aug 13 20:50:26 2016
Func2 Task --- No.0 start at   Sat Aug 13 20:50:26 2016


Traceback (most recent call last):
  File "threading_test.py", line 20, in <module>
    t1.setDaemon(False)
  File "/usr/lib/python2.7/threading.py", line 1036, in setDaemon
    self.daemon = daemonic
  File "/usr/lib/python2.7/threading.py", line 1029, in daemon
    raise RuntimeError("cannot set daemon status of active thread");
RuntimeError: cannot set daemon status of active thread
Func2 Task --- No.1 start at    Sat Aug 13 20:50:28 2016
Func1 Task --- No.1 start at    Sat Aug 13 20:50:29 2016
瞧,主线程没有打印结果
  ● 加入join()观察一下结果:
#coding = utf-8
import threading
from time import ctime,time,sleep
threads = []


def task1(num):
        for i in range(num):
                print ('Func1 Task --- No.%d start at\t%s' %(i,ctime(time())))
                sleep(3)


def task2(num):
        for i in range(num):
                print ('Func2 Task --- No.%d start at\t%s' % (i, ctime(time())))
                sleep(5)


if __name__ == '__main__':
        t1 = threading.Thread(target = task1, args = (2,))
        t2 = threading.Thread(target = task2, args = (2,))
        threads.append(t1)
        threads.append(t2)


        for t in threads:
                t.setDaemon(True)
                t.start()
        t.join()


        print ('Main Function End\t %s' % ctime())
执行结果如下:
root@root2:~/file_xlwu/f1/tmp# python threading_test.py
Func1 Task --- No.0 start at    Sat Aug 13 21:18:05 2016
Func2 Task --- No.0 start at   Sat Aug 13 21:18:05 2016
Func1 Task --- No.1 start at    Sat Aug 13 21:18:08 2016
Func2 Task --- No.1 start at    Sat Aug 13 21:18:10 2016
Main Function End        Sat Aug 13 21:18:15 2016
由此可以看到,setDaemon只是为了设置主程序是否要退出程序,而join()函数则是为了将程序阻塞到这里,阻止主程序的继续执行,从而实现阻塞主线程,等待子线程执行完之后才执行之后代码的功能。
另外,The for-loop makes assignments to the variable(s) in the target list. 
This overwrites all previous assignments to those variables including those made in the suite of the for-loop. 
The target list is not deleted when the loop is finished. 
But if the sequence is empty, they will not have been assigned to at all the loop. 
也就是说for循环中的target list(for x in range(10) x 就是target list)在循环结束中并未被删除,可以被后续程序直接使用。但除一种情况外:循环序列为空时,target list根本不会被赋值。 
这个根源还在于,Python中的for循环并没有引入作用域(scope)的概念,但函数定义有引入作用域。 什么意思呢? 如果你希望for循环变量不被其他程序误用/覆盖等,可以把for循环单独放在一个函数内。 
可以在Ipython中进行实验, 
for i in range(10): 
pass 
print i 
可以看到打印的i显示i的值是9
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值