Python 3.7.1 模块 并发执行 底层线程API _thread


该模块提供了用于处理多线程(也称为轻量级进程或任务)的低级原语- 多个控制线程共享其全局数据空间。为了同步,提供了简单的锁(也称为互斥锁或二进制信号量)。 threading模块提供了一个基于此模块构建的更易于使用和更高级别的线程API。

版本3.7中已更改:此模块曾经是可选的,现在始终可用。

1._thread 函数

该模块定义了以下常量和函数:

exception _thread.error

引发特定于线程的错误。

在版本3.3中更改:现在是内置RuntimeError的同义词。

_thread.LockType

这是锁定对象的锁的类型。

_thread.start_new_thread(function, args[, kwargs])

启动一个新线程并返回其标识符。线程使用参数列表args(必须是元组)执行function函数。可选的 kwargs参数指定关键字参数的字典。当函数返回时,线程将以静默方式退出。当函数以未处理的异常终止时,将打印堆栈跟踪,然后线程退出(但其他线程继续运行)。

_thread.interrupt_main()

在主线程中引发KeyboardInterrupt异常。子线程可以使用此函数来中断主线程。

_thread.exit()

引发SystemExit异常。未捕获时,这将导致线程以静默方式退出。

_thread.allocate_lock()

返回一个新的锁对象。锁的方法如下所述。锁最初是非锁定的。

_thread.get_ident()

返回当前线程的“线程标识符”。这是一个非零整数。它的值没有直接意义; 它旨在用作例如索引线程特定数据的字典的 magic cookie。当线程退出并创建另一个线程时,可以回收线程标识符。

_thread.stack_size([size])

返回创建新线程时使用的线程堆栈大小。可选的 size参数指定用于后续创建的线程的堆栈大小,并且必须为0(使用平台或已配置的默认值)或至少为32,768(32 KiB)的正整数值。如果未指定size,则使用0。如果不支持更改线程堆栈大小,则引发RuntimeError。如果指定的堆栈大小无效,则引发ValueError,堆栈大小未经修改。32 KiB是目前支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。请注意,某些平台可能对堆栈大小的值有特定限制,例如要求最小堆栈大小> 32 KiB或需要以系统内存页面大小的倍数进行分配 - 应参考平台文档以获取更多信息(4 KiB页面很常见;在没有更具体信息的情况下,建议的方法是使用4096的倍数作为堆栈大小)。

可用性:Windows,具有POSIX线程的系统。

_thread.TIMEOUT_MAX

允许Lock.acquire()的timeout参数最大值。指定超过此值的超时将引发一个OverflowError。

版本3.2中的新功能。

2.lock函数

锁对象具有以下方法:

lock.acquire(waitflag=1, timeout=-1)

在没有任何可选参数的情况下,此方法无条件地获取锁,如果有必要,等待它被另一个线程释放(一次只有一个线程可以获取锁定 - 这就是它们存在的原因)。

如果存在整数waitflag参数,则操作取决于其值:如果它为零,则仅在不等待的情况下立即获取锁定时获取锁定,而如果它非零,则如上所述无条件地获取锁定。

如果浮点型timeout参数存在且为正,则它指定返回之前的最长等待时间(以秒为单位)。负 timeout参数指定无限制等待。如果waitflag为零,则无法指定超时。

如果成功获取锁定则返回值True,否则 返回值False。

改变在3.2版本:该超时参数是新增加的。

在版本3.2中更改:现在可以通过POSIX上的信号中断锁定获取。

lock.release()

释放锁定。必须先获取锁,但不一定是同一个线程。

lock.locked()

返回锁的状态:如果已被某个线程获取返回True, 如果没有返回False。

3.其它

除了这些方法之外,还可以通过with语句使用锁定对象 ,例如:

import _thread

a_lock = _thread.allocate_lock()

with a_lock:
    print("a_lock is locked while this executes")

注意事项:

  • 线程与中断奇怪地交互:KeyboardInterrupt 异常将由任意线程接收。(当signal 模块可用时,中断始终转到主线程。)
  • 调用sys.exit()或抛出SystemExit异常等同于调用_thread.exit()。
  • 无法在锁定时中断acquire()方法 - KeyboardInterrupt异常发生在锁被accquired之后。
  • 当主线程退出时,系统决定其他线程是否存活!在大多数系统中,它们在不执行 try… finally子句或执行对象析构函数的情况下被终止。
  • 当主线程退出时,它不执行任何常规清理(除了try… finally子句被使用),并且不刷新标准I / O文件。

4.实例

这里引用了网友的 实例,特此说明

#!/usr/bin/env python3
# coding:utf-8
from time import ctime
from time import sleep
import _thread

loops = [4, 2, 3, 5]


def loop(nloop, nsec, lock):    # 参数依次为:标识,睡眠时间,锁对象
    print("start loop", nloop, 'at:', ctime())
    sleep(nsec)
    print("loop", nloop, "done at:", ctime())
    lock.release()  # 释放锁


def main():
    print('start at:', ctime())
    locks = []
    nloops = range(len(loops))

    for i in nloops:
        lock = _thread.allocate_lock()  # 分配锁对象
        lock.acquire()  # 获取锁对象
        locks.append(lock)

    for i in nloops:
        _thread.start_new(loop, (i, loops[i], locks[i]))

    # 等待所有锁被释放
    for i in nloops:
        while(locks[i].locked()):
            pass
    print('all DONE at', ctime())


if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/lengfengyuyu/article/details/84946698