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


    进击の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('我是主线程... ...')
    
    

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

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


    *****
    *****
  • 相关阅读:
    IOS控件Label(UILabel)
    利用 sys.sysprocesses 检查 Sql Server的阻塞和死锁
    PowerShell 定时执行.Net(C#)程序
    Sql Server 2012 转换函数的比较(Cast、Convert 和 Parse)
    Sql Server 编译、重编译与执行计划重用原理
    Windows Server 2008 R2 下安装 Sql Server 2012 初体验
    Sql Server 批量导出索引、存储过程、视图和函数
    IOS UIImage
    C# 分析 IIS 日志(Log)
    Sql Server 2012 分页方法分析(offset and fetch)
  • 原文地址:https://www.cnblogs.com/jevious/p/11402223.html
Copyright © 2020-2023  润新知