#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量

    num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 0

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量

    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 0

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量

    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    time.sleep(0.1)  # 时间长,线程切换变量就覆盖
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 99

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量

    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    time.sleep(0.0001)  # 时间长,线程切换变量就覆盖
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 65

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量

    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    time.sleep(0.00001)  # 时间长,线程切换变量就覆盖
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 54

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量

    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    print('ok')
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
okok

okok

ok
okok

ok
ok
okok

ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
okok

ok
okok

ok
ok
okok
ok

ok
ok
okok

ok
okok

ok
okok

ok
ok
ok
ok
okok

ok
okok

okok

ok
ok
okok

okok

ok
ok
ok
ok
okok
ok

ok
okok

okok

ok
okok

okok

ok
ok
ok
ok
final num: 41

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    print('ok')
    num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    # temp = num
    # print('ok')
    # num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
ok
ok
ok
ok
okok

ok
ok
ok
ok
ok
okok

okok

okok

ok
ok
ok
ok
ok
ok
okok

ok
ok
okok

ok
ok
ok
okok
ok

ok
ok
ok
ok
okok

ok
okok

okok

ok
okok

ok
okok

ok
okok
ok

ok
ok
ok
ok
okok
ok

ok
okok
ok
ok

ok
ok
ok
ok
ok
ok
okok
ok

ok
okok

ok
ok
ok
okok
ok

ok
ok
okok
ok

ok
ok
okok

ok
ok
ok
okok

final num: 0

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    print('ok')
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
ok
ok
ok
ok
okok

ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
okok

ok
ok
ok
okok

ok
ok
okok

ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
okok

ok
okok
ok

ok
okok

ok
ok
okok

ok
okok

ok
okok
ok

ok
okok

ok
ok
ok
ok
okok
ok

ok
okok
ok

okok
ok

ok
okok

ok
okok

ok
okok
ok

ok
okok
ok

okok

okok

ok
okok
ok

ok
okok
ok

final num: 50

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    # print('ok')
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 0

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    temp = num
    time.sleep(0.1)
    num = temp - 1

num = 100   #设定一个共享变量

thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 99

Process finished with exit code 0

注意:

1:why num-=1没有问题呢?这是因为动作太快(完成这个动作在切换的世界内)

2:if sleep(1),现象会更明显,100个线程每一个一定都没有执行完就进行了切换,我们说过sleep就等效于IO阻塞,1s之内不会切换回来,所以最后的结果一定是99

多个线程都在同时操作同一个共享资源,所以会造成了资源破坏,怎么办呢?

有同学会想用join呗,但join会把整个线程给停住,造成了串行,失去了多线程的意义,而我们只需要把计算(涉及到操作公共数据)的时候串行执行。

我们可以通过同步锁来解决这种问题

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    r.acquire()    #加锁,使用锁只是加锁和解锁之间的代码执行使用串行,但是前面和后面还是多线性。
    temp = num
    time.sleep(0.00001)
    num = temp - 1
    r.release()  # 解锁,仅计算的程序变成串行,锁的是线程。

num = 100   #设定一个共享变量

thread_list = []
r = threading.Lock()    #声明一把锁对象
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 0

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    r.acquire()    #加锁,使用锁只是加锁和解锁之间的代码执行使用串行,但是前面和后面还是多线性。
    temp = num
    time.sleep(1)
    num = temp - 1
    r.release()  # 解锁,仅计算的程序变成串行,锁的是线程。

num = 100   #设定一个共享变量

thread_list = []
r = threading.Lock()    #声明一把锁对象
for i in range(10):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 90

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    # r.acquire()    #加锁,使用锁只是加锁和解锁之间的代码执行使用串行,但是前面和后面还是多线性。
    temp = num
    time.sleep(0.01)
    num = temp - 1
    # r.release()  # 解锁,仅计算的程序变成串行,锁的是线程。

num = 100   #设定一个共享变量

thread_list = []
r = threading.Lock()    #声明一把锁对象
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    t.join()    #使用join()整个程序会变成串行
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
final num: 0

Process finished with exit code 0

#!/usr/bin/env python3.8
# -*- coding: UTF-8 -*-
# __author: smoke
# file: syn_lock
# time: 2021/04/01

import time
import threading

def addNum():
    global num  #在每个线程中都获取这个全局变量
    # num -= 1   #num -= 1的时候cpu不能切换,好在num-=1不够cpu切换时间,当再把num赋值给别的变量就会出问题
    print('ok')
    r.acquire()    #加锁,使用锁只是加锁和解锁之间的代码执行使用串行,但是前面和后面还是多线性。
    temp = num
    time.sleep(0.01)
    num = temp - 1
    r.release()  # 解锁,仅计算的程序变成串行,锁的是线程。

num = 100   #设定一个共享变量

thread_list = []
r = threading.Lock()    #声明一把锁对象
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    # t.join()    #使用join()整个程序会变成串行
    thread_list.append(t)

for t in thread_list:   #等待所有线程执行完毕
    t.join()

print('final num:', num)

/home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/venv/bin/python /home/smoke/文档/DocumentFile/PycharmProjects/pythonProject/join/syn_lock.py
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
okok

ok
ok
ok
ok
ok
ok
okok

ok
ok
ok
ok
ok
ok
ok
ok
okok

ok
ok
okok
ok

ok
ok
ok
ok
ok
ok
ok
ok
ok
okok

ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
okok

ok
ok
ok
ok
ok
ok
ok
okok

ok
ok
okok

ok
okok

okok

okok

ok
ok
ok
ok
ok
ok
okok

ok
final num: 0

Process finished with exit code 0