本人测试,在网上找了这段多线程代码做接口测试,求大佬们看看为什么子线程走完了一直不继续运行

2019-12-16 10:04:20 +08:00
 as1997121000

coding:utf-8

import requests import threading from queue import Queue import time num_xian = input("请输入要执行的线程数:")

添加线程

threadList = int(num_xian)

设置队列长度

workQueue = Queue(10)

线程池

threads = [] stare = time.time()

def crawler(threadName, q): # 执行多线程 # 从队列里取出数据 j = q.get(timeout=2) try: print('线程:' + threadName) except Exception as e: print(q.qsize(), threadName, "号线程运行错误 ", e)

class myThread(threading.Thread): def init(self, name, q): threading.Thread.init(self) self.name = name self.q = q def run(self): try: print(self.name + "号线程启动 ") crawler(self.name, self.q) print(self.name + "号线程结束 ") except: print(self.name + "号线程启动失败 ")

创建新线程

for tName in range(1,threadList+1): thread = myThread(tName, workQueue) thread.start() threads.append(thread)

读取数据,放入队列

filename = '文件名.txt' f = open(filename, 'r', encoding="utf-8").readlines()

for i in f: workQueue.put(i)

等待所有线程完成

for t in threads: t.join()

end = time.time() print('Queue 多线程批量执行时间为:', end - start)

4245 次点击
所在节点    Python
22 条回复
gefranks
2019-12-16 10:06:18 +08:00
看到排版 实力劝退了
simenet
2019-12-16 10:45:20 +08:00
看得我老壳痛
luozic
2019-12-16 12:28:24 +08:00
改一下排版。
no1xsyzy
2019-12-16 13:13:19 +08:00
这个排版,笑傻了
as1997121000
2019-12-16 14:43:52 +08:00
@gefranks @luozic @simenet @no1xsyzy sorry,见笑,添加了附言,但不知道空格该怎么表示了
RyanOne
2019-12-16 14:50:10 +08:00
排版 劝退 ,晒图 ,或者 gist
as1997121000
2019-12-16 16:46:07 +08:00
@RyanOne 重新贴了代码了,不好意思
cherbim
2019-12-16 16:48:47 +08:00
crawler 里加上最上面加个 while true 啊,你没有在队伍里取东西,就每次创建子线程的时间取一次,然后队伍不取完,子线程无法退出,就一直在那里闲着(正常从队伍取不到东西线程报错然后退出,少了循环),
简单说:
创建第一个子线程,crawler 执行,从队伍取个元素,然后它闲着了...
创建第二个子线程,crawler 执行,从队伍在取个元素,然后它闲着了...
创建第三个子线程,crawler 执行,从队伍再取个元素,然后它闲着了...
...
线程创建完毕,然后一堆线程在那里划水
helloSpringBoot
2019-12-16 17:04:24 +08:00
2 个问题:
1. 文件行数大于 queue 大小了怎么办?
2. 线程数大于 queue 中数据大小了,后面获取不到数据的线程怎么办?
as1997121000
2019-12-16 17:21:42 +08:00
@helloSpringBoot
1.文件行数大于 queue 大小了怎么办?
期望是不管,大于了不读就行了,如果能够实现开多少线程读多少行最好
2. 线程数大于 queue 中数据大小了,后面获取不到数据的线程怎么办?
as1997121000
2019-12-16 17:23:20 +08:00
@helloSpringBoot
2. 线程数大于 queue 中数据大小了,后面获取不到数据的线程怎么办?
等待,或者定个总时间,例如 30 秒没跑完继续走
crackhopper
2019-12-16 17:33:40 +08:00
我测了没问题
开头:stare 改成 start
然后没发现问题了。
as1997121000
2019-12-16 17:54:44 +08:00
@crackhopper 我运行两个线程结果:
1 号线程启动
2 号线程启动
线程:2 线程:1
2 号线程结束
1 号线程结束
‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’
然后程序就不走了,在想是不是读取的文件行数比线程数多,线程池一直没释放
as1997121000
2019-12-16 17:56:30 +08:00
@cherbim 运行结果:
请输入要执行的线程数:2
1 号线程启动
1 号线程启动失败
2 号线程启动
2 号线程启动失败
as1997121000
2019-12-16 18:00:13 +08:00
@crackhopper @helloSpringBoot @cherbim 我试了下把文件的行数缩小到 3 行,线程大于 3,就能正常结束了,所以这代码在想怎么改能开几个线程就读几行
cherbim
2019-12-16 19:34:20 +08:00
@as1997121000 你复制我的代码试试,我运行正常,
https://paste.ubuntu.com/p/8x52MxbZ93/
cherbim
2019-12-16 19:36:26 +08:00
@cherbim 补充一下,我的 saas_user_mini.txt 文件设置为 1-18,存入队列后每次读取后输出
no1xsyzy
2019-12-16 23:52:14 +08:00
1. 没有死循环,结果是开几个线程就是处理几行
2. 没有终止标志,无论是设 Condition 还是给队列喂 Stop Symbol,你得让它可控终止
3. Queue.get 带 timeout 参数却不捕获 Empty

这前置知识缺失问题很重,我甚至不知道从哪开始讲,先看基本模型吧……

我习惯上来说偏好喂 Stop Symbol
https://gist.github.com/no1xsyzy/43c9490250d7efac0f4ba6704d26a72f
no1xsyzy
2019-12-16 23:52:46 +08:00
@cherbim 不会闲着,会直接退出,这时候 .join() 会直接返回
as1997121000
2019-12-17 10:10:42 +08:00
@as1997121000 我试了下,我的文件有上千条数据,现在是运行后线程是读完了这行就去读了下一行,等到文件读完了才停下
@no1xsyzy 你的代码我试着变成了一个线程读多行并输出然后文件读完了才结束
我把文件传百度云盘了,各位大佬可以参考下 aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVFUa3lvbjkwYndrOWZoWW1vWGdmMUE=

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/629363

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX