python的join和daemon

 

其他基本概念

# 进程,线程,协程
# 串行,并行,并发
# 同步/异步 阻塞/非阻塞
#
#
# python 的多线程败笔:
# 多进程可以并行,然而由于GIL锁的缘故,导致同一时刻,同一进程,只能有一个线程运行。
# 多线程不可进行并行。
#
# 并行是最快的,并发速度稍微慢点
# join:主线程开始,等待当前子线程完成,才结束主线程
# daemon守护线程:跟随主线程,主线程结束,子线程直接结束,步调和主线程保持一致

基本例子

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
"""
from ycyj_zhongtai.apis_gongshi.free_fast_search.ffs_base import dzh_data_req

# from ycyj_zhongtai.service_ref.dzh_hqdata import DzhF10Api
# obj = DzhF10Api()
# res = obj.get_f10_十大股东('300546.SZ')
# print(res)
#
# for item in res:
#     print(item)


# 生成大智慧token
token = dzh_data_req.get_dzh_token()

# url = 'http://gw.yundzh.com/f10/cwts/lrfpbzy?field=jlr&start=-6&count=6&obj=600171.SH&Obj=SZ300928&token={}'.format(token)
# print(url)
#
# url = 'http://gw.yundzh.com/f10/gdjc/sdgd?field=Zjqk&start=-1&count=1&token={}&obj={}'.format(token, 'SZ300478')
# print(url)
#
# url = 'http://gw.yundzh.com/f10/cwts/zycwzb?field=xsmll&start=-1&count=1&token={}&obj={}'.format(token, 'SH600519')
# print(url)

# 净资产收益率
# url = 'http://gw.yundzh.com/f10/cpbd/zxzb?field=jzcsyl,zylrtbzz,jlrtbzz&start=-1&count=1&token={}&obj={}'.format(token, 'SZ300088')
# print(url)


import logging
import time
import threading

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s [%(threadName)s] %(message)s')


def worker1):
    logging.info('starting1')
    time.sleep(13)
    logging.info('stopping1')


def worker2():
    logging.info('starting2')
    time.sleep(1)
    logging.info('stopping2')


if __name__ == '__main__':
    logging.info('0')
    t1 = threading.Thread(target=worker1, name='worker1', daemon=False)
    t1.start()
    time.sleep(1)
    t2 = threading.Thread(target=worker2, name='worker2', daemon=True)
    t2.start()
    logging.info('1')

  

 

一般默认子线程setDaemon(False),这样主线程和子线程各干各的,都执行完毕结束
子线程setDaemon(True),这样主线程完毕,不管子线程有没有结束,直接杀掉结束
join,主线程会等子线程全部结束,才结束

业务场景需要主线程等子线程执行完毕结束的用join
业务场景需要各自执行完毕的,什么也不干涉,什么也不用写
业务场景只需要主线程干活,子线程无所谓的,设置守护线程,但是感觉好像没什么意义
# 计算密集型:大量使用cpu且占据,python多线程不好使 
# IO密集型:存在大量IO操作,python多线程好使 
# python 使用多核: 
# 用进程弊端:开销大,切换复杂 
# 解决方案:协程 本质上是单线程 
# 方向:IO多路复用 
# 终极思路:换C模块实现多线程 
# (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。 
# (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 
# (3)CPU分给线程,即真正在CPU上运行的是线程。 
# 并行处理(Parallel Processing)是计算机系统中能同时执行两个或更多个处理的一种计算方法。 
# 并行处理可同时工作于同一程序的不同方面。 
# 并行处理的主要目的是节省大型和复杂问题的解决时间。 
# 并发处理(concurrency Processing):指一个时间段中有几个程序都处于已启动运行到运行完毕之间, 
# 且这几个程序都是在同一个处理机(CPU)上运行,但任一个时刻点上只有一个程序在处理机(CPU)上运行 
# 并发的关键是你有处理多个任务的能力,不一定要同时。
# 并行的关键是你有同时处理多个任务的能力。所以说,并行是并发的子集

  

join和daemon的基本使用举例:

# join:等待当前线程完成,才执行主线程(取决于子线程)
# daemon守护线程:跟随主线程,主线程结束,子线程直接结束,步调和主线程保持一致(取决于主线程)
# join():在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
# 换句话解释:要等绑定这个方法的对象执行完毕才可以执行主线程。

# setDaemon(True):
'''
         将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。

         当我们在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程 就分兵两路,分别运行。
         
         那么当主线程完成,想退出时,会检验子线程是否完成。
         如果子线程未完成,则主线程会等待子线程完成后再退出。
         
         但是有时候我们需要的是只要主线程完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以 用setDaemon方法
'''


import threading
from time import ctime,sleep
import time

def Music(name):

        print ("Begin listening to {name}. {time}".format(name=name,time=ctime()))
        sleep(3)
        print("end    listening {time}".format(time=ctime()))

def Blog(title):

        print ("Begin recording the {title}. {time}".format(title=title,time=ctime()))
        sleep(5)
        print('end    recording {time}'.format(time=ctime()))


threads = []


t1 = threading.Thread(target=Music,args=('FILL ME',))
t2 = threading.Thread(target=Blog,args=('',))

threads.append(t1)
threads.append(t2)

if __name__ == '__main__':

    #t2.setDaemon(True)

    for t in threads:

        #t.setDaemon(True) #注意:一定在start之前设置
        t.start()
        t.join()  #等价于必须某程序结束以后才能执行主程序

    #t1.join()  #阻塞主线程,等t1结束,然后进行主线程
    #t2.join()    #  考虑这三种join位置下的结果?

    print ("all over %s" %ctime())

  

# -*- coding:utf-8 -*-

import threading
import time

def run():
    time.sleep(2)
    print('当前线程的名字是: ', threading.current_thread().name)
    time.sleep(2)


if __name__ == '__main__':

    start_time = time.time()

    print('这是主线程:', threading.current_thread().name)
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.setDaemon(True)
        t.start()

        # t.join()

    print('一共用时:', time.time() - start_time)
    print('主线程结束!' , threading.current_thread().name)

  

 



 

posted @ 2017-09-21 13:22  Adamanter  阅读(301)  评论(0编辑  收藏  举报