~~并发编程(八):开启线程~~

进击のpython

*****

并发编程——开启进程


学知识除了要纵向吸收,还要学会横向对比

这样类比学习就容易简单的多

线程的学习就可以根据进程的学习来进行参考

这一节我们可以尝试着使用threading模块开启线程

通过掌握threading模块开启线程的两种方式

(我连上一句话都是照着线程的那个文章扒下来的)


threading模块

multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍


Thread类

class Thread:

    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, *, daemon=None):
        if kwargs is None:
            kwargs = {}
        self._target = target
        self._name = str(name or _newname())
        self._args = args
        self._kwargs = kwargs
        if daemon is not None:
            self._daemonic = daemon
        else:
            self._daemonic = current_thread().daemon
        self._ident = None
        self._tstate_lock = None
        self._started = Event()
        self._is_stopped = False
        self._initialized = True
        # sys.stderr is not stored in the class like
        # sys.exc_info since it can be changed between instances
        self._stderr = _sys.stderr
        # For debugging and _after_fork()
        _dangling.add(self)

介绍一下参数:

group:参数未使用,值始终是None

target:表示调用对象,即子线程要执行的任务(就是塞进去一个你想执行的函数)

args:表示调用对象的位置参数元祖(就是对函数进行传参)

kwargs:表示调用对象的字典(就是对函数进行传参)

name:子线程的名字

介绍一下属性:

t.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程

​ 当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程

​ 必须在start之前设置
​ 2.name:线程的名称

def start(self):
    if not self._initialized:
        raise RuntimeError("thread.__init__() not called")

    if self._started.is_set():
        raise RuntimeError("threads can only be started once")
    with _active_limbo_lock:
        _limbo[self] = self
    try:
        _start_new_thread(self._bootstrap, ())
    except Exception:
        with _active_limbo_lock:
            del _limbo[self]
        raise
    self._started.wait()


def run(self):
    try:
        if self._target:
            self._target(*self._args, **self._kwargs)
    finally:
        # Avoid a refcycle if the thread is running a function with
        # an argument that has a member that points to the thread.
        del self._target, self._args, self._kwargs


def join(self, timeout=None):
    if not self._initialized:
        raise RuntimeError("Thread.__init__() not called")
    if not self._started.is_set():
        raise RuntimeError("cannot join thread before it is started")
    if self is current_thread():
        raise RuntimeError("cannot join current thread")

    if timeout is None:
        self._wait_for_tstate_lock()
    else:
        # the behavior of a negative timeout isn't documented, but
        # historically .join(timeout=x) for x<0 has acted as if timeout=0
        self._wait_for_tstate_lock(timeout=max(timeout, 0))


def is_alive(self):
    assert self._initialized, "Thread.__init__() not called"
    if self._is_stopped or not self._started.is_set():
        return False
    self._wait_for_tstate_lock(False)
    return not self._is_stopped


def isAlive(self):
    import warnings
    warnings.warn('isAlive() is deprecated, use is_alive() instead',
                  PendingDeprecationWarning, stacklevel=2)
    return self.is_alive()


@property
def daemon(self):
    assert self._initialized, "Thread.__init__() not called"
    return self._daemonic


@daemon.setter
def daemon(self, daemonic):
    if not self._initialized:
        raise RuntimeError("Thread.__init__() not called")
    if self._started.is_set():
        raise RuntimeError("cannot set daemon status of active thread")
    self._daemonic = daemonic
    

接下来介绍一下方法:

start():启动线程,并调用该子线程中的run()

run(): 线程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法

is_alive():如果p仍然运行,返回True

join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)

​ timeout是可选的超时时间


Thread的使用

首先很重要的一点就是,在windows系统,线程的开启必须放到if name == 'main':的下面

第一种方法

from threading import Thread


def func(name, *args, **kwargs):
    print(f'{name}执行!')
    pass


if __name__ == '__main__':
    p = Thread(target=func, args=('子线程',))
    p.start()
    print('我是主线程... ...')

在主进程中创建一个子进程,用来执行函数func,并对函数进行传参

然后利用start进行声明子进程

第二种方法

from threading import Thread


class Mythread(Thread):
    """这是Mythread"""

    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        print(f'{self.name}执行!')


if __name__ == '__main__':
    p = Mythread('子线程')
    p.start()
    print('我是主线程... ...')

这种方法用的太少了,就看一下了解一下就行

更多的还是第一种方法的使用


*****
*****
原文地址:https://www.cnblogs.com/jevious/p/11402223.html