注:这篇文章部分为廖雪峰py3教程:点我,本文使用python3.5
(1)thread模块不支持守护线程,守护线程表示这个线程不是重要的,进程退出时不需要等待这个线程执行完成。在python的另一个模块threading中支持守护线程。
(2)threading.current_thread().name:获取当前线程的名字
(3)线程实例.start():线程开始执行
(4)线程实例.join():等待目前正在执行的线程执行完毕
(5)线程实例.daemon = True:设置该线程为守护线程
例子一:
import timeimport threadingdef run_func(): print('[+]thread %s is running...' % threading.current_thread().name) cnt = 0 while cnt < 5: cnt += 1 print('thread %s >>> %s' % (threading.current_thread().name, cnt)) time.sleep(1) print('thread %s ended' % threading.current_thread().name)if __name__ == '__main__': print('thread %s is running..' % threading.current_thread().name) t = threading.Thread(target=run_func, name='LoopThread') t.start() t.join() print('[+]thread %s ended' % threading.current_thread().name)例子二:import threadingimport timedef func(slp): name = threading.current_thread().name print('[+]thread%s start at ' % name, time.ctime()) time.sleep(slp) print('[+]thread%s end at ' % name, time.ctime())if __name__ == '__main__': trds = list() slps = [x*2 for x in range(1, 5)] for each in range(4): trds.append(threading.Thread(target=func, args=(slps[each], ))) print('[+]main time start at', time.ctime()) for each in trds: each.start() for each in trds: each.join() print('[+]main time end at ', time.ctime())'''output:[+]main time start at Sun Feb 5 17:02:13 2017[+]threadThread-1 start at Sun Feb 5 17:02:13 2017[+]threadThread-2 start at Sun Feb 5 17:02:13 2017[+]threadThread-3 start at Sun Feb 5 17:02:13 2017[+]threadThread-4 start at Sun Feb 5 17:02:13 2017[+]threadThread-1 end at Sun Feb 5 17:02:15 2017[+]threadThread-2 end at Sun Feb 5 17:02:17 2017[+]threadThread-3 end at Sun Feb 5 17:02:19 2017[+]threadThread-4 end at Sun Feb 5 17:02:21 2017[+]main time end at Sun Feb 5 17:02:21 2017'''import threadingimport timedef func(output, sleeptime): print('[+]start at', time.ctime()) print('%s' % threading.current_thread().name, output) time.sleep(sleeptime) print('[+]end at', time.ctime())if __name__ == '__main__': sleeptime = 5 thr = threading.Thread(name='lrh', target=func, args=('test now...', sleeptime)) thr.daemon = True thr.start() '''#设置为守护线程后,程序执行完thr.start()后就开始退出,#由于执行了sleep(),输出是不会同时有start at 时间,end at 时间的 #output:[+]start at Thu Feb 16 17:40:07 2017'''线程锁
进程之间的变量是拷贝的,而线程是共用变量,所有当多个线程存在时需要限制其他线程不能使用,仅某个线程可以使用,这就是线程锁,import threadingimport osimport timeimport randombalance = 0lock = threading.Lock()def run_func(n): global balance balance = balance + n balance = balance - ndef run_thread(n): for each in range(10000): lock.acquire() try: run_func(n) except Exception as error: print(error) finally: lock.release()t1 = threading.Thread(target=run_thread, args=(5000099,))t2 = threading.Thread(target=run_thread, args=(100000,))t1.start()t2.start()t1.join()t2.join()print(balance)多个线程执行lock.acquire()时,只有一个线程能成功的获取锁,其他线程只能等待,所以一定要记得释放锁此外,在python中可以使用上下文管理,即使用with语句。多核cpu:
import threadingimport multiprocessingdef loop(): x = 0 while True: x = x ^ 1for i in range(multiprocessing.cpu_count()): t = threading.Thread(target=loop) t.start()由于GIL全局锁把所有的线程的执行上了锁,多线程在python中只能交替的运行,即使100个线程跑在100核cpu上,也只能用到一个核ThreadLocal,解决多线程局部变量的传递问题
由于线程之间的全局变量是共用的,所以对于一个线程来说,使用局部变量是最好的,避免影响其他线程之间的变量,那么就会有一个问题,局部变量在传递起来就会比较麻烦一个可行的思路是使用线程名字作为key,value来存放待传递变量python给我们提供了更加方便的做法,使用ThreadLocalimport threadinglocalSet = threading.local()def func_run(): std = localSet.student print('Hello, %s (in %s)' % (std, threading.current_thread().name))def thread_run(name): localSet.student = name func_run()if __name__ == '__main__': t1 = threading.Thread(target=thread_run, args=('lrh', ), name='Thread-A') t2 = threading.Thread(target=thread_run, args=('kch',), name='Thread-B') t1.start() t2.start() t1.join() t2.join()
新闻热点
疑难解答