(对于线程篇的一些基本了解)
什么是线程?
在一个进程的内部要同时干多件事,就需要同时运行多个子任务,我们把进程内的这些子任务叫做线程;
线程通常叫做轻型的进程,线程事共享内存空间的并发执行的多任务,每一个线程都共享一个进程的资源;
线程是最小的执行单元,而进程有至少一个线程组成;
如何调度进程和线程,完全由操作系统决定,程序自己是不能决定什么时候执行和执行多长时间。(这些有操作系统决定的)
关于模块:
1. _thread模块 低级模块(接近底层C语言写的)
2. threading模块 高级模块,对_thread进行了封装
# 启动一个线程 import threading, time def run(a): print('子线程--{}--开始'.format(threading.current_thread().name)) # 实现线程的功能 time.sleep(2) print('打印', a) print('子进程--{}--结束'.format(threading.current_thread().name)) if __name__ == '__main__': # 任何进程默认就会启动一个线程,成为主线程,主线程可以启动新的子线程 print('主线程({})启动'.format(threading.current_thread())) # 创建子线程 t = threading.Thread(target=run, args=(1,), name='runThread') t.start() # 等待线程结束 t.join() print('主线程({})结束'.format(threading.currnet_thread()))
# 线程间共享数据 ''' 多线程和多进程最大的不同在于:多进程中,同一个变量,各自有一份拷贝在每个进程中,互不影响。 而多线程中,所有变量都由所有线程共享。所以任何一个变量都可以被任意一个线程修改。 因此线程之间共享数据最大的危险,多个线程同时修改一个变量,容易把内容改乱 ''' import threading num = 100 def run(n): global num for i in range(100000): num += n num -= n if __name__ == '__main__': t1 = threading.Thread(target=run, args=(6,)) t2 = threading.Thread(target=run, args=(9,)) t1.start() t2.start() t1.join() t2.join() print('num = ', num)
# 你会发现修改的数字不一定是100,这个不知道要怎么解释,可能对一个数字调用次数太多,然后计数器混乱,共享资源混乱。
# 线程锁解决数据混乱 ''' 两个线程同时工作、一个存钱、一个取钱 可能导致数据异常,就像上一个 解决思路: ''' import threading lock = threading.Lock() num = 100 def tun(n): global num for i inrange(100000): # 为线程加一把锁,确保这段代码只能有一个线程从头到尾完整执行,阻止多线程的并发执行,包含锁的某段代码实际上只能以单线程模式执行,所以效率大大降低了 #优于它可以存在多个锁,不同线程持有不同的锁,并试图获取其他的锁,这样可能造成多个线程挂起,这样只能靠操作系统强制终止 ''' try: lock.acquire() num += n num -= n finally: # 修改完一定要释放锁 lock.release() ''' # 与上面代码功能相同,with.lock可以自动上锁与解锁 with lock: num += n num -= n