鱼C论坛

 找回密码
 立即注册
查看: 3471|回复: 8

[已解决]Py: 加锁问题,我看不懂程序

[复制链接]
发表于 2021-6-8 15:57:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 Peteryo01223 于 2021-6-8 16:00 编辑

问题:以下程序中,
  • lk 是我自己命名的,请问,lk 它是一个变量吗?
  • lk 是如何与 lock 配合,成功加锁的呢?我怎么看不到它俩在程序中的联系呀?
  • with lk,如果换成写 with each,也能成功加锁,是吗?

# 线程安全
import threading
import time
number = 0
lock = threading.Lock()


def add(lk):
    global number
    # 加锁
    with lk:
        for _ in range(1000000):
            number += 1
        print('子线程 %s 执行结束后:number = %d' % (threading.current_thread().getName(), number))
        # 解锁
        

for i in range(2):
    t = threading.Thread(target=add, args = (lock,))
    t.start()


time.sleep(3)
print('主线程结束, number = ' + str(number))
最佳答案
2021-6-9 09:33:22
Peteryo01223 发表于 2021-6-9 09:30
你的代码,我试了一下,报错了。是不是有个变量名,没改?



Python 3.8 以上 time.clock 改成了 time.perf_counter ,你改下即可

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-6-8 19:29:24 | 显示全部楼层

你 lk 是定义函数中的参数,当然可以随便命名的,开启线程时的 args 参数就是线程的传入参数,将 lock 这个锁已经传递给 lk 了

如果你换成 each ,那么如果 each 也是你创建的一个锁,当然可以,若不是锁就不行,另外代码改成这样好看出来些

你会发现线程一起开始且停下的时间也都为 2s 但是先加锁的先执行完毕,后加锁的后执行
# 线程安全
import threading
import time

number = 0
lock = threading.Lock()


def add(lk):
    global number
    # 加锁
    with lk:
        time.sleep(2)
        thread_time = time.clock()
        print('子线程 %.4f 总执行时间' % (thread_time - start_time))
        # 解锁


for i in range(2):
    start_time = time.clock()
    t = threading.Thread(target=add, args=(lock,))
    t.start()
    print(f'开始进程{i+1}')

print('主线程结束')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-9 09:30:44 | 显示全部楼层
本帖最后由 Peteryo01223 于 2021-6-9 09:34 编辑
Twilight6 发表于 2021-6-8 19:29
你 lk 是定义函数中的参数,当然可以随便命名的,开启线程时的 args 参数就是线程的传入参数,将 lock 这 ...

Traceback (most recent call last):
  File "C:/Users/user/AppData/Local/Programs/Python/Python38/202101125a.py", line 20, in <module>
    start_time = time.clock()
AttributeError: module 'time' has no attribute 'clock'
>>> 
问题:
1. 你的代码,我试了一下,报错了,如上。是不是有个变量名,没改?
2. 感谢你耐心的简介。你说:lk 是定义函数中的参数,当然可以随便命名的,开启线程时的 args 参数就是线程的传入参数,将 lock 这个锁已经传递给 lk 了。我还是没看懂。
t = threading.Thread(target=add, args=(lock,))
上面这一句,跟 lk 有什么关系呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-9 09:33:22 | 显示全部楼层    本楼为最佳答案   
Peteryo01223 发表于 2021-6-9 09:30
你的代码,我试了一下,报错了。是不是有个变量名,没改?



Python 3.8 以上 time.clock 改成了 time.perf_counter ,你改下即可

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-9 09:49:56 | 显示全部楼层
Twilight6 发表于 2021-6-9 09:33
Python 3.8 以上 time.clock 改成了 time.perf_counter ,你改下即可

成功了。
# 线程安全
import threading
import time

number = 0
lock = threading.Lock()


def add(lk):
    global number
    # 加锁
    with lk:
        time.sleep(2)
        thread_time = time.perf_counter()
        print('子线程 %.4f 总执行时间' % (thread_time - start_time))
        # 解锁


for i in range(2):
    start_time = time.perf_counter()
    t = threading.Thread(target=add, args=(lock,))
    t.start()
    print(f'开始进程{i+1}')

print('主线程结束')
run后结果:
开始进程1
开始进程2
主线程结束
>>> 子线程 1.9267 总执行时间
子线程 3.9983 总执行时间
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-9 09:53:31 | 显示全部楼层
Twilight6 发表于 2021-6-9 09:33
Python 3.8 以上 time.clock 改成了 time.perf_counter ,你改下即可

lk 和 with lk,我还是没明白,能帮我再进一步,解释一下么?他们是怎么起到 lock 的作用的?看不出 lk 和 lock 之间的联系。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-9 09:56:20 | 显示全部楼层
Peteryo01223 发表于 2021-6-9 09:53
lk 和 with lk,我还是没明白,能帮我再进一步,解释一下么?他们是怎么起到 lock 的作用的?看不出 lk  ...




这里 for 循环的 print 我打错了,不是进程是线程

def add(lk):
     ......

t = threading.Thread(target=add, args=(lock,))


就是 add 函数往其中传入了 lock 变量,lock 不就赋值到 lk 上了吗

相当于 lk 是 lock 的别名
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-9 10:15:40 | 显示全部楼层
Twilight6 发表于 2021-6-9 09:56
这里 for 循环的 print 我打错了,不是进程是线程

好的 再次感谢您
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-9 10:28:40 | 显示全部楼层

没事没事
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-8 05:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表