V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
as1997121000
V2EX  ›  Python

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

  •  
  •   as1997121000 · 2019-12-16 10:04:20 +08:00 · 4340 次点击
    这是一个创建于 1789 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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)

    第 1 条附言  ·  2019-12-16 14:43:09 +08:00
    # 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 = 'saas_user_mini.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)
    第 2 条附言  ·  2019-12-16 14:58:44 +08:00
    # 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 = 'saas_user_mini.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)
    
    22 条回复    2019-12-17 10:37:06 +08:00
    gefranks
        1
    gefranks  
       2019-12-16 10:06:18 +08:00 via iPhone
    看到排版 实力劝退了
    simenet
        2
    simenet  
       2019-12-16 10:45:20 +08:00
    看得我老壳痛
    luozic
        3
    luozic  
       2019-12-16 12:28:24 +08:00
    改一下排版。
    no1xsyzy
        4
    no1xsyzy  
       2019-12-16 13:13:19 +08:00
    这个排版,笑傻了
    as1997121000
        5
    as1997121000  
    OP
       2019-12-16 14:43:52 +08:00
    @gefranks @luozic @simenet @no1xsyzy sorry,见笑,添加了附言,但不知道空格该怎么表示了
    RyanOne
        6
    RyanOne  
       2019-12-16 14:50:10 +08:00
    排版 劝退 ,晒图 ,或者 gist
    as1997121000
        7
    as1997121000  
    OP
       2019-12-16 16:46:07 +08:00
    @RyanOne 重新贴了代码了,不好意思
    cherbim
        8
    cherbim  
       2019-12-16 16:48:47 +08:00
    crawler 里加上最上面加个 while true 啊,你没有在队伍里取东西,就每次创建子线程的时间取一次,然后队伍不取完,子线程无法退出,就一直在那里闲着(正常从队伍取不到东西线程报错然后退出,少了循环),
    简单说:
    创建第一个子线程,crawler 执行,从队伍取个元素,然后它闲着了...
    创建第二个子线程,crawler 执行,从队伍在取个元素,然后它闲着了...
    创建第三个子线程,crawler 执行,从队伍再取个元素,然后它闲着了...
    ...
    线程创建完毕,然后一堆线程在那里划水
    helloSpringBoot
        9
    helloSpringBoot  
       2019-12-16 17:04:24 +08:00
    2 个问题:
    1. 文件行数大于 queue 大小了怎么办?
    2. 线程数大于 queue 中数据大小了,后面获取不到数据的线程怎么办?
    as1997121000
        10
    as1997121000  
    OP
       2019-12-16 17:21:42 +08:00
    @helloSpringBoot
    1.文件行数大于 queue 大小了怎么办?
    期望是不管,大于了不读就行了,如果能够实现开多少线程读多少行最好
    2. 线程数大于 queue 中数据大小了,后面获取不到数据的线程怎么办?
    as1997121000
        11
    as1997121000  
    OP
       2019-12-16 17:23:20 +08:00
    @helloSpringBoot
    2. 线程数大于 queue 中数据大小了,后面获取不到数据的线程怎么办?
    等待,或者定个总时间,例如 30 秒没跑完继续走
    crackhopper
        12
    crackhopper  
       2019-12-16 17:33:40 +08:00
    我测了没问题
    开头:stare 改成 start
    然后没发现问题了。
    as1997121000
        13
    as1997121000  
    OP
       2019-12-16 17:54:44 +08:00
    @crackhopper 我运行两个线程结果:
    1 号线程启动
    2 号线程启动
    线程:2 线程:1
    2 号线程结束
    1 号线程结束
    ‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’
    然后程序就不走了,在想是不是读取的文件行数比线程数多,线程池一直没释放
    as1997121000
        14
    as1997121000  
    OP
       2019-12-16 17:56:30 +08:00
    @cherbim 运行结果:
    请输入要执行的线程数:2
    1 号线程启动
    1 号线程启动失败
    2 号线程启动
    2 号线程启动失败
    as1997121000
        15
    as1997121000  
    OP
       2019-12-16 18:00:13 +08:00
    @crackhopper @helloSpringBoot @cherbim 我试了下把文件的行数缩小到 3 行,线程大于 3,就能正常结束了,所以这代码在想怎么改能开几个线程就读几行
    cherbim
        16
    cherbim  
       2019-12-16 19:34:20 +08:00
    @as1997121000 你复制我的代码试试,我运行正常,
    https://paste.ubuntu.com/p/8x52MxbZ93/
    cherbim
        17
    cherbim  
       2019-12-16 19:36:26 +08:00
    @cherbim 补充一下,我的 saas_user_mini.txt 文件设置为 1-18,存入队列后每次读取后输出
    no1xsyzy
        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
        19
    no1xsyzy  
       2019-12-16 23:52:46 +08:00
    @cherbim 不会闲着,会直接退出,这时候 .join() 会直接返回
    as1997121000
        20
    as1997121000  
    OP
       2019-12-17 10:10:42 +08:00
    @as1997121000 我试了下,我的文件有上千条数据,现在是运行后线程是读完了这行就去读了下一行,等到文件读完了才停下
    @no1xsyzy 你的代码我试着变成了一个线程读多行并输出然后文件读完了才结束
    我把文件传百度云盘了,各位大佬可以参考下 aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVFUa3lvbjkwYndrOWZoWW1vWGdmMUE=
    as1997121000
        21
    as1997121000  
    OP
       2019-12-17 10:11:36 +08:00
    @cherbim @helloSpringBoot @crackhopper 文件我传百度云了,大佬们可以参考下 aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVFUa3lvbjkwYndrOWZoWW1vWGdmMUE=
    as1997121000
        22
    as1997121000  
    OP
       2019-12-17 10:37:06 +08:00
    @no1xsyzy 感谢大佬,我把执行函数的 while True 去了就是我想要的结果了,感谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2749 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:40 · PVG 20:40 · LAX 04:40 · JFK 07:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.