线程
进程:程序执行产生
每个进程都有自己的地址空间,内存,数据栈,以及用于跟踪执行的辅助数据
程序执行可能产生多个进程,
线程:在进程内执行,相当于一个迷你进程,同一进程下的多个线程共享信息,一个进程下必有一个主线程,线程是CPU的执行单位
Python下开线程:threading模块
threading 模块建立在thread 模块之上。thread模块以低级、原始的方式来处理和控制线程,而threading 模块通过对thread进行二次封装,提供了更方便的api来处理线程。
import threading #线程 import time def hi(num): print("%d hello" %num) time.sleep(3) if __name__ == "__main__": # 实例化一个线程对象,两个参数,第一个是被执行的变量名,第二个是被执行的程序的参数,元组类型 t1 = threading.Thread(target=hi,args=(4,)) t1.start() t2 = threading.Thread(target=hi,args=(7,)) t2.start() #开线程后,两个线程实现并发效果
import threading
import time
def music(): print("begin to listen %s" %time.ctime()) time.sleep(3) print("stop to listen %s" %time.ctime()) def game(): print("going to play %s" %time.ctime()) time.sleep(5) print("stop to play %s" %time.ctime()) if __name__ == '__main__': t1 = threading.Thread(target=music) t2 = threading.Thread(target=game) t1.start() #线程执行 # t1.join() t2.start() t1.join() #执行join方法时,根据join的插入的位置不同,决定怎么执行线程,Python程序是从上向下依次执行 t2.join() print("ending...")
#此时是3个线程并发,但Python程序是从上向下依次执行,在一个线程 执行前 加上另一个线程的join方法,就会阻碍这个线程执行
直至那个使用join方法的线程执行结束
import threading import time
def music(): print("begin to listen %s" %time.ctime()) time.sleep(3) print("stop to listen %s" %time.ctime()) def game(): print("going to play %s" %time.ctime()) time.sleep(5) print("stop to play %s" %time.ctime()) threads = [] t1 = threading.Thread(target=music) t2 = threading.Thread(target=game) threads.append(t1) threads.append(t2) if __name__ == '__main__': for t in threads: t.setDaemon(True) #守护线程,必须放在start之前,主线程结束,子线程也立即结束 t.start()
#将线程声明为守护进程,必须在start()方法调用之前设置,
当我们在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程就兵分两路,分别运行,那么当主线程完成想退出时,会检验子进程是否完成。
如果子进程未完成,则主线程会等待子线程完成后再退出。但有些时候我们需要的是,只要主线程完成了,不管子进程是否完成,都要和主线程一起退出,这时候就可以用setDaemon方法。
# 继承式调用 import threading import time class MyThread(threading.Thread): def __init__(self, num): threading.Thread.__init__(self) self.num = num def run(self): # 定义每个线程要运行的函数 print('running on number: %s' % self.num) time.sleep(3) if __name__ == '__main__': t1 = MyThread(1) t2 = MyThread(2) t1.start() t2.start() print('ending...')
线程的一些方法:
# run(): 线程被cpu调度后自动执行线程对象的run方法 # start():启动线程活动。 # isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。 threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量。 # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。