PyThon 多线程
PyThon 多线程
快速入门
先上代码
import time
import threading # 1
def sing():
for i in range(5):
print("1")
time.sleep(1)
def dance():
for i in range(5):
print("2")
time.sleep(1)
def dance1():
for i in range(5):
print("3")
time.sleep(1)
def dance2():
for i in range(5):
print("4")
time.sleep(1)
def main():
t1 = threading.Thread(target=sing) # 指定函数
t2 = threading.Thread(target=dance)
t3 = threading.Thread(target=dance1)
t4 = threading.Thread(target=dance2)
t1.start()
t2.start()
t3.start()
t4.start()
if __name__ == '__main__':
main()
结果
进阶
指定函数 ===> 动态传参 ===> 共享全局变量
资源竞争
1+1=1???
同步就是协同步调﹐按预定的先后次序进行运行。如:你说完﹐我再说·
"同"字从字面上容弟理解为一起动作
其实不是﹐"同"字应是指协同·协助·互相配合。
如进程﹑线程同步﹐可理解为进程或线程A和B一块配合﹐A执行到一定程度时要依靠B的某个结果﹐于是停下来﹐示意B运行;B执行﹐再将结果给A;A再继续操作·
解决线程同时修改全局变量的方式
线程同步来进行解决同步出错而难题:
1.系统调用t1﹐然后获取到g_num的值为0﹐此时上一把锁﹐即不允许其他线程操作g_num2.t1对g_num的值进行+1
3.t1解锁﹐此时g_num的值为1﹐其他的线程就可以使用g_num了﹐而且是g_num的值不是0而是1
4.同理其他线程在对g_num进行修改时﹐都要先上锁﹐处理完后再解锁﹐在上锁的整个过程中不允许其
他线程访问﹐就保证了数据的正确性
线程同步
互斥锁
当多个线程几乎同时修改某一个共享数据的时候﹐需要进行同步控制
线程同步能够保证多个线程安全访问竞争资源﹐最简单的同步机制是引入互斥锁。
互斥锁为资源引入—状态∶锁定/非锁定
某个线程要更改共享数据时﹐先将其锁定﹐此时资源的状态为“锁定”﹐其他线程不能更改﹔直到该线程释放资源﹐将资源的状态变成“非锁定”﹐其他的线程才能再次锁定该资源·互斥锁保证了每次只有一个线程进行写入操作﹐从而保证了多线程情况下数据的正确性。
#创建锁
mutex= threading.Lock()
#锁定
mutex.acquire()
#释放
mutex.release()
过程
import threading
import time
# 定义一个全局变量
g_num = 0
def test1(num):
global g_num
# 上锁,如果之前没有被上锁,那么此时上锁成功
# 如果上锁之前已经被上锁了,那么此时会堵塞在这里,直到这个锁被解开为止
mutex.acquire()
for i in range(num):
g_num += 1
mutex.release()
print(" - ----in test1 g_num=%d----" % g_num)
def test2(num):
global g_num
mutex.acquire()
for i in range(num):
g_num += 1
mutex.release()
print(" -----in test2 g_num=%d=----" % g_num)
def test3(num):
global g_num
for i in range(num):
mutex.acquire()
g_num += 1
mutex.release()
print(" -----in test3 g_num=%d=----" % g_num)
def test4(num):
global g_num
for i in range(num):
mutex.acquire()
g_num += 1
mutex.release()
print(" -----in test4 g_num=%d=----" % g_num)
# 创建—个互斥锁,默认是没有上锁的
mutex = threading.Lock()
def main():
t1 = threading.Thread(target=test1, args=(1000000,))
t2 = threading.Thread(target=test2, args=(1000000,))
t3 = threading.Thread(target=test1, args=(1000000,))
t4 = threading.Thread(target=test2, args=(1000000,))
t1.start()
t2.start()
time.sleep(2)
print("-----in main Thread g_num = %d---" % g_num)
t3.start()
t4.start()
# 等待上面的2个线程执行完毕....
if __name__ == '__main__':
main()
结果
- ----in test1 g_num=1000000----
-----in test2 g_num=2000000=----
-----in main Thread g_num = 2000000---
- ----in test1 g_num=3000000----
-----in test2 g_num=4000000=----
Process finished with exit code 0
# 为什么?????
死锁
在线程间共享多个资源的时候﹐如果两个线程分别占有一部分资源并且同时等待对方的资源﹐就会死锁。
# coding=utf-8
import threading
import time
class MyThread1(threading.Thread):
def run(self):
# 对mutexA上锁
mutexA.acquire()
# mutexA上锁后﹐延时1秒﹐等待另外那个线程把mutexB上锁
print(self.name + '----do1---up--—-')
time.sleep(1)
# 此时会堵塞﹐因为这个mutexB已经被另外的线程抢先上锁了
mutexB.acquire()
print(self.name + '—---do1---down----')
mutexB.release()
# 对mutexA解锁
mutexA.release()
class MyThread2(threading.Thread):
def run(self):
# 对mutexB上锁
mutexB.acquire()
# mutexB上锁后﹐延时1秒·等待另外那个线程把mutexA上锁
print(self.name + '----do2---up----')
time.sleep(1)
# 此时会堵塞﹐因为这个mutexA已经被另外的线程抢先上锁了
mutexA.acquire()
print(self.name + '----do2---down----')
mutexA.release()
# 对mutexB解锁
mutexB.release()
mutexA = threading.Lock()
mutexB = threading.Lock()
if __name__ == '_main__':
t1 = MyThread1()
t2 = MyThread2()
t1.start()
t2.start()
结果
Thread-1----do1---up----
Thread-2----do2---up----
后期更精彩...
纵饮孤独,程序员的世界是孤独的,这个平台让我们聚集在一起纵饮百年孤独