time.sleep 不适用于多线程

Posted

技术标签:

【中文标题】time.sleep 不适用于多线程【英文标题】:time.sleep does not work for multithreaded 【发布时间】:2021-12-02 00:25:56 【问题描述】:

当我发现time.sleep() 没有挂起运行pywin32 模块的线程时,我正试图对"Suspend / Hibernate pc with python" 提供的"Suspend / Hibernate pc with python" 进行多线程处理。

>>> 警告!以下代码将使 Windows 进入睡眠状态

def suspend(buffer, hibernate=False):
    '''Puts Windows to Suspend/Sleep/Standby or Hibernate.

    Parameters
    ----------
    buffer: string, for time.sleep()
    hibernate: bool, default False
        If False (default), system will enter Suspend/Sleep/Standby state.
        If True, system will Hibernate, but only if Hibernate is enabled in the
        system settings. If it's not, system will Sleep.

    Example:
    --------
    >>> suspend()
    '''
    print('before sleep') 
    sleep(float(buffer))
    print('after sleep')
    # Enable the SeShutdown privilege (which must be present in your
    # token in the first place)
    priv_flags = (win32security.TOKEN_ADJUST_PRIVILEGES |
                  win32security.TOKEN_QUERY)
    hToken = win32security.OpenProcessToken(
        win32api.GetCurrentProcess(),
        priv_flags
    )
    priv_id = win32security.LookupPrivilegeValue(
        None,
        win32security.SE_SHUTDOWN_NAME
    )
    old_privs = win32security.AdjustTokenPrivileges(
        hToken,
        0,
        [(priv_id, win32security.SE_PRIVILEGE_ENABLED)]
    )

    if (win32api.GetPwrCapabilities()['HiberFilePresent'] == False and
            hibernate == True):
        import warnings
        warnings.warn("Hibernate isn't available. Suspending.")
    try:
        windll.powrprof.SetSuspendState(not hibernate, True, False)
    except:
        # True=> Standby; False=> Hibernate
        # https://msdn.microsoft.com/pt-br/library/windows/desktop/aa373206(v=vs.85).aspx
        # says the second parameter has no effect.
        #        ctypes.windll.kernel32.SetSystemPowerState(not hibernate, True)
        win32api.SetSystemPowerState(not hibernate, True)

    # Restore previous privileges
    win32security.AdjustTokenPrivileges(
        hToken,
        0,
        old_privs
    )


if __name__ == '__main__':
    Thread(target=suspend, args=("10")).start()

print 函数确实等待了time.sleep(),但 Windows 立即进入睡眠状态。 发生了什么?

【问题讨论】:

【参考方案1】:

您在调用Thread 时错误地将缓冲区参数传递给sleep 1.0 秒。您需要在 args 关键字参数的值末尾添加逗号 ,,如下所示:

.
.
if __name__ == '__main__':
    Thread(target=suspend, args=("10",)).start()

【讨论】:

你是对的。我刚刚意识到args 是一个元组。非常感谢。 我自己有点惊讶,因为在大多数情况下,当将一个参数作为参数传递时,您不需要输入逗号,但如果第一个参数是一个字符串,那么它显然是必要的。就个人而言,我总是把它放进去,因为它不会伤害而且更明确。问题:为什么首先将此参数作为字符串而不是浮点数传递? 对。我也很惊讶。 buffer 在许多其他实例中用作字符串,所以我想我会在需要时将其解析为浮动。除此之外,如果我不小心将 int 或 float 作为参数传入也没有什么坏处。

以上是关于time.sleep 不适用于多线程的主要内容,如果未能解决你的问题,请参考以下文章

python,多线程应用示例

PythonStudy——多线程与多进程 对比

多线程

Python3 多线程 学习 threading

python多线程join/setDaemon

多任务--线程