鱼C论坛

 找回密码
 立即注册
查看: 698|回复: 4

[已解决]请教一个多线程的问题!!悬赏20

[复制链接]
发表于 2019-6-4 11:15:24 | 显示全部楼层 |阅读模式
20鱼币
本帖最后由 hjx123hjx 于 2019-6-4 17:24 编辑

先贴下我的代码
  1. import requests
  2. import threading

  3. def threaded_crawler(max_threads=5):
  4.     def get_text(data):
  5.         nonlocal i
  6.         i += 1

  7.         url = 'http://httpbin.org/post'
  8.         print('old offset ', data['offset'])
  9.         resp = requests.post(url, data=data)
  10.         print('new offset ', data['offset'])


  11.     i = 0
  12.     threads = []
  13.     while True:
  14.         # 检查线程池
  15.         for thread in threads:
  16.             if not thread.is_alive():
  17.                 # 移除执行完毕的线程
  18.                 threads.remove(thread)
  19.         # 小于最大线程数时添加线程
  20.         while len(threads) < max_threads:
  21.             data['offset'] += 1
  22.             thread = threading.Thread(target=get_text, args=(data,))
  23.             thread.setDaemon(True)
  24.             thread.start()
  25.             threads.append(thread)
  26.         # 堵塞线程
  27.         for thread in threads:
  28.             thread.join()

  29.         # 退出循环
  30.         if i == 8:
  31.             break
  32.             
  33. def main():
  34.     threaded_crawler()

  35. data = {
  36.     'offset': 0
  37. }
  38. main()
  39. input()
复制代码

执行效果如下图:
1559617027.png
我想要的效果是每次传入的data['offset']参数分别为1-8,执行效果可以看到传入requests.post之前还是不同的,传入的时候就变成统一的5和8了。。
这是怎么回事?为什么在requests.post这里几个线程要卡住然后再一起执行?希望大佬解释一下多线程的执行步骤。。谢谢!!
方便的话提点一下怎么改才能达到我想要的效果。。
微信图片_20190604172225.png
最佳答案
2019-6-4 11:15:25
你声明了nonlocal i,所以当多线程执行的时候,不同线程的i的值会互相影响

最佳答案

查看完整内容

你声明了nonlocal i,所以当多线程执行的时候,不同线程的i的值会互相影响
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-4 11:15:25 | 显示全部楼层    本楼为最佳答案   
你声明了nonlocal i,所以当多线程执行的时候,不同线程的i的值会互相影响
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-6-4 17:23:31 | 显示全部楼层
2012277033 发表于 2019-6-4 15:29
你声明了nonlocal i,所以当多线程执行的时候,不同线程的i的值会互相影响

额。。我设置i只是设置一个退出条件。。data是我要传给网站的参数。
不过你的思路没错。外面传入的一个data确实在不同线程中会相互影响。所以我给网站传参前在各个线程中copy一份,这样就能保证要传的参数不变了。
  1. def get_text(data):
  2.     nonlocal i
  3.     i += 1

  4.     formdata = data.copy()
  5.     url = 'http://httpbin.org/post'
  6.     print('old offset ', formdata)
  7.     resp = requests.post(url, data=formdata)
  8.     print(resp.text)
复制代码

感谢大佬提供的思路!!呃,我还有一个小问题,新的执行效果图在原问题上。
为何在post前执行print('old offset ', formdata)时会按顺序执行,之后执行print(resp.text)就不按顺序了,我应该对线程同步执行有一些疑问。。希望大佬能帮我解答一下!谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-4 17:38:22 | 显示全部楼层
hjx123hjx 发表于 2019-6-4 17:23
额。。我设置i只是设置一个退出条件。。data是我要传给网站的参数。
不过你的思路没错。外面传入的一个d ...

额,因为网络请求有快有慢的,多线程下,可能B线程访问的请求快于A线程,那么B线程的打印就会在A线程之前了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-6-4 20:08:03 | 显示全部楼层
2012277033 发表于 2019-6-4 17:38
额,因为网络请求有快有慢的,多线程下,可能B线程访问的请求快于A线程,那么B线程的打印就会在A线程之前 ...

嗯。有些明白了,谢谢大佬解惑!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-17 19:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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