Python v3线程和操作系统上下文切换(从v2改为?)

时间:2018-01-20 13:19:22

标签: python python-3.x priority-queue python-multithreading context-switch

我用python 3线程击中了死胡同。示例脚本在某种程度上是微不足道的,而它的行为与以前的python版本(使用python 2.7测试)相比有所不同 我们的想法是启动函数(to_time_it()),它等待一个线程(thread_it())来清除一些标志。线程连续运行直到最后,两个函数内的sleep()确保python必须用while语句汇集标志。

问题是,python v2(在我的情况下为.7)运行速度更快,几乎确定性更快,在我的HP(win10,Intel i5,32bit python v2.7)或更早版本上大约(10 + 5)= 15 ms linux pc。虽然相同的代码在python 3.6上运行正常,但是如果某些while循环内部存在一些无意义的printsleep(0),则会导致此10ms延迟,外。这是代码:

# -*- coding: utf-8 -*-

import os
import time as systime
import timeit
import threading

flag = False
thread_flag = False

counter = 0

AVERAGE = 10

def thread_it():
    global flag
    global thread_flag

    #run thread until thread_flag is not set
    while not thread_flag:
        while flag:
            # (1)
            #print("")
            #systime.sleep(0)
            pass

        #print("!")
        systime.sleep(0.05) # force to_time_it() to wait thread to set flag

        flag = True # return to thread while loop

def to_time_it():
    global flag
    global counter 

    flag = False    # break out of thread while loop 
    #   - > to systime.sleep() after #(1) and than set flag

    # wait thread to set flag (thread is than waiting for new cycle in it's while loop)
    systime.sleep(0.03) 

    while not flag: # wait for flag (approx 20ms)
        # (2)
        #print("")
        #systime.sleep(0)
        pass    # do nothing

    print("OK: %s" %counter) # thread has cleared flag, can start new cycle
    counter += 1


def main():
    global thread_flag
    global flag

    print("Threading while loop test")

    th = threading.Thread(target=thread_it)
    th.start()

    tajm = timeit.timeit(to_time_it, number=AVERAGE) * 1000 / AVERAGE

    systime.sleep(0.7)  #not neccesary, just to see what is happening when printing out data

    # exit/end thread
    thread_flag = True
    flag = False

    print("\n\tAverage time: %.2f ms" % tajm)

    #os._exit(1)

if __name__ == '__main__':
    main()

此代码在两个python版本上运行速度相同的点标记为# (1)# (2)。事实证明,一个简单的print("")time.sleep(0)进行一些内部更改,导致在python 3上运行时消除此延迟。将其中任何一个添加到点#(1)会导致10毫秒延迟消失,并向点#(2)添加任何内容会导致其他5毫秒消失。我不知道为什么while something: pass的处理方式与while something: time.sleep(0)不同。将passsleep()print()移至外部功能无效。

我假设有关python线程模块的一些更改必须在v3中发生,导致操作系统上下文切换/进程或线程优先级处理在较新版本上采取不同的行为。任何人都可以测试这个并解释/解释吗?

注意: I already started a similar question,但我没有得到任何回复。我开始了一个新主题(不是评论/编辑),因为我设法剥离了pyserial的测试脚本依赖项,因为我相信这是一个更普遍的python问题。请将我重定向到更好的地方,或者让我知道让专家看看这个案例的其他方法。

0 个答案:

没有答案