鱼C论坛

 找回密码
 立即注册
查看: 2162|回复: 2

[已解决]各位大佬,实在想不出来了,函数值赋给列表的问题,哪位大佬帮忙给看一下,跪谢

[复制链接]
发表于 2023-9-8 01:21:18 | 显示全部楼层 |阅读模式

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

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

x
[code]import threading
from pynput.mouse import Listener

x_list = []
y_list = []

def on_click(x, y, button, pressed):
    global x_list,y_list
    print("鼠标位置为:{},执行操作为:{},是否点击或松开:{}".format((x, y), button, pressed))
    if pressed == True:
        x_list.append(x)
        y_list.append(y)
        print(x_list)
def ls_k_thread():
    with Listener(on_click=on_click) as listener:
        listener.join()

def analyse_pic_thread():
    r = threading.Thread(target=ls_k_thread)
    r.start()
analyse_pic_thread()

print(x_list)

                               
登录/注册后可看大图
最佳答案
2023-9-8 01:21:41
关于函数值赋给列表的问题

您的代码存在一个问题:在主线程打印 x_list 的时候,可能会出现列表为空的情况。这是因为 on_click 函数运行在一个单独的线程中,并且在主线程打印 x_list 之前,子线程没有足够的时间将数据添加到列表中。

解决这个问题的方法是,使用互斥锁(mutex lock)来确保在访问共享的 x_listy_list 时的线程安全。

下面是修改后的代码:
  1. import threading
  2. from pynput.mouse import Listener
  3. x_list = []
  4. y_list = []
  5. mutex = threading.Lock()  # 创建互斥锁
  6. def on_click(x, y, button, pressed):
  7.     global x_list, y_list
  8.     print("鼠标位置为:{}, 执行操作为:{}, 是否点击或松开:{}".format((x, y), button, pressed))
  9.    
  10.     if pressed:
  11.         mutex.acquire()  # 获取锁
  12.         try:
  13.             x_list.append(x)
  14.             y_list.append(y)
  15.             print(x_list)
  16.         finally:
  17.             mutex.release()  # 释放锁
  18. def ls_k_thread():
  19.     with Listener(on_click=on_click) as listener:
  20.         listener.join()
  21. def analyse_pic_thread():
  22.     r = threading.Thread(target=ls_k_thread)
  23.     r.start()
  24. analyse_pic_thread()
  25. # 主线程暂时休眠1秒钟,以等待子线程将数据添加到列表中
  26. time.sleep(1)
  27. # 打印结果(注意:子线程可能仍在运行,列表可能会继续增加)
  28. print(x_list)
复制代码

在上述代码中,我们添加了一个互斥锁 mutex,并在访问 x_listy_list 时使用 mutex.acquire() 获取锁,在访问结束后使用 mutex.release() 释放锁。这样可以确保在修改列表时只有一个线程进行操作,从而避免了数据竞争和不一致的问题。

另外,在主线程打印 x_list 前,我们使用 time.sleep(1) 让主线程暂停1秒钟,以等待子线程将数据添加到列表中。

希望以上修改能够解决您的问题。如果还有其他问题,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-9-8 01:21:36 | 显示全部楼层
问题的关键在于线程的执行顺序。在你的代码中,主线程会立即打印 x_list ,但是 x_list 在子线程中被修改,所以打印出来的结果是空列表。解决这个问题的一种方法是使用线程同步机制,确保子线程执行完毕后再打印 x_list 。

可以使用 threading.Event 来实现线程同步。下面是修改后的代码:

  1. import threading
  2. from pynput.mouse import Listener

  3. x_list = []
  4. y_list = []
  5. event = threading.Event()

  6. def on_click(x, y, button, pressed):
  7.     global x_list, y_list
  8.     print("鼠标位置为:{},执行操作为:{},是否点击或松开:{}".format((x, y), button, pressed))
  9.     if pressed == True:
  10.         x_list.append(x)
  11.         y_list.append(y)
  12.         print(x_list)

  13.         # 通知主线程子线程执行完毕
  14.         event.set()

  15. def ls_k_thread():
  16.     with Listener(on_click=on_click) as listener:
  17.         listener.join()

  18. def analyse_pic_thread():
  19.     r = threading.Thread(target=ls_k_thread)
  20.     r.start()

  21. # 启动子线程
  22. analyse_pic_thread()

  23. # 等待子线程执行完毕
  24. event.wait()

  25. # 打印结果
  26. print(x_list)
复制代码


这样修改后,主线程会等待子线程执行完毕后再打印 x_list ,确保打印的结果是子线程修改后的列表。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-9-8 01:21:41 | 显示全部楼层    本楼为最佳答案   
关于函数值赋给列表的问题

您的代码存在一个问题:在主线程打印 x_list 的时候,可能会出现列表为空的情况。这是因为 on_click 函数运行在一个单独的线程中,并且在主线程打印 x_list 之前,子线程没有足够的时间将数据添加到列表中。

解决这个问题的方法是,使用互斥锁(mutex lock)来确保在访问共享的 x_listy_list 时的线程安全。

下面是修改后的代码:
  1. import threading
  2. from pynput.mouse import Listener
  3. x_list = []
  4. y_list = []
  5. mutex = threading.Lock()  # 创建互斥锁
  6. def on_click(x, y, button, pressed):
  7.     global x_list, y_list
  8.     print("鼠标位置为:{}, 执行操作为:{}, 是否点击或松开:{}".format((x, y), button, pressed))
  9.    
  10.     if pressed:
  11.         mutex.acquire()  # 获取锁
  12.         try:
  13.             x_list.append(x)
  14.             y_list.append(y)
  15.             print(x_list)
  16.         finally:
  17.             mutex.release()  # 释放锁
  18. def ls_k_thread():
  19.     with Listener(on_click=on_click) as listener:
  20.         listener.join()
  21. def analyse_pic_thread():
  22.     r = threading.Thread(target=ls_k_thread)
  23.     r.start()
  24. analyse_pic_thread()
  25. # 主线程暂时休眠1秒钟,以等待子线程将数据添加到列表中
  26. time.sleep(1)
  27. # 打印结果(注意:子线程可能仍在运行,列表可能会继续增加)
  28. print(x_list)
复制代码

在上述代码中,我们添加了一个互斥锁 mutex,并在访问 x_listy_list 时使用 mutex.acquire() 获取锁,在访问结束后使用 mutex.release() 释放锁。这样可以确保在修改列表时只有一个线程进行操作,从而避免了数据竞争和不一致的问题。

另外,在主线程打印 x_list 前,我们使用 time.sleep(1) 让主线程暂停1秒钟,以等待子线程将数据添加到列表中。

希望以上修改能够解决您的问题。如果还有其他问题,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-22 19:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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