import threading
import time

class Mythead(threading.Thread):
    '''线程守护'''
    def __init__(self ):
        super(Mythead, self).__init__()
        pass
        
    def set_task(self, func, *args):
        self.func = func
        self.args = args

    def run(self):
        # print(f" ---  {len(self.args)}")
        if len(self.args) > 0:
            self.func(self.args)
        else:
            self.func( )

class Multithread(threading.Thread):
    '''
    多线程
    子线程.join() -> ( 设置在start之后, 等所有阻塞线程运行完, 再运行主线程 )
    子线程.setDaemon(True) -> 设置子线程A为守护线程, 主线程所在的进程内所有非守护线程统统运行完毕,
                            无论子线程A有没有结束, 程序都结束    
    Method:

    '''
    def __init__(self):
        super(Multithread, self).__init__()
        self.__tasks  = []
        self.act = []
        # self.__block    = False
        pass
        
    # def set_task( self, tasks ):
    #     self.__tasks  = tasks
        
    def add_task(self, func, daemon=False, join=True,args=()):
        tmp_dict = {}
        tmp_dict.update( {"func" : func})
        if daemon == True:
            tmp_dict.update( {"daemon" : True})
        else:
            tmp_dict.update( {"daemon" : False})    
        if join == True:
            tmp_dict.update( {"join" : True})
        else:
            tmp_dict.update( {"join" : False})                              
        if args == ():        
            tmp_dict.update( {"args" : ()})
        else:
            tmp_dict.update( {"args" : args})            
        self.__tasks.append( tmp_dict )
        
    def remove_tasks(self,  ):
        self.__tasks  = []
        self.act = []
        
    def add_task_2_act(self, task):
        t = threading.Thread( target = task['func'], args = task['args'] )
        self.act.append(t)
        t.start()   
        
    def execute_one_act(self,i):
        if self.__tasks[i]['join']:
            self.act[i].join() # 子线程阻塞完毕再运行主线程                
        pass      
        
    def prepare_tasks(self):
        self.act = []
        for task in self.__tasks:
            self.add_task_2_act(task)
                        
    def execute_tasks(self):
        try:
            for i in range( len(self.act) ):
                self.execute_one_act( i )               
                pass            
        except Exception as e:
            print(e)
            
    def prepare_tasks(self):
        self.act = []
        for task in self.__tasks:
            t = threading.Thread( target = task['func'], args = task['args'] )
            self.act.append(t)
            t.start()
                        
    def simultaneously_execute_tasks(self):
        self.prepare_tasks()
        self.execute_tasks()
        
    def sequently_execute_tasks(self):
        for task in self.__tasks:
            t = threading.Thread( target = task['func'], args = task['args'] ) 
            t.start()
            t.join()     
     
            
    def t1(self):
        print("thread1...")
        time.sleep(10)
        print("thread1... after sleep...")
        
    def t2(self):
        print("thread2...")
        time.sleep(5)
        print("thread2... after sleep...")
        
    def t3(self):        
        print("thread3...")
        time.sleep(3)
        print("thread3... after sleep...")
            
if __name__ == '__main__':
    mt = Multithread()
    mt.add_task(mt.t1)
    mt.add_task(mt.t2)
    mt.add_task(mt.t3)
    # mt.prepare_tasks()  # 线程同步运行
    # mt.execute_tasks()
    # mt.simultaneously_execute_tasks()
    mt.sequently_execute_tasks()
    
