今天了解了下python中的线程,做下笔记,方便后续回忆
什么是多线程?
多线程简单来说就是指CPU可以同时做多任务,比如CPU可以同时做任务A,也可以做任务B,但是一个CPU的话是不能完全实现并行的,只能实现并发(也就是在多个任务之间快速切换)
在python中如何创建线程?
在python中我们需要使用threading模块中的thread类
查看源码发现其实对于thread类中多线程的使用是用的run这个方法,那么我们可以直接继承thread类,重写run这个方法就可以了
下面是thread类中的init方法和run方法
1 class Thread: 2 """A class that represents a thread of control. 3 4 This class can be safely subclassed in a limited fashion. There are two ways 5 to specify the activity: by passing a callable object to the constructor, or 6 by overriding the run() method in a subclass. 7 8 """ 9 10 _initialized = False 11 # Need to store a reference to sys.exc_info for printing 12 # out exceptions when a thread tries to use a global var. during interp. 13 # shutdown and thus raises an exception about trying to perform some 14 # operation on/with a NoneType 15 _exc_info = _sys.exc_info 16 # Keep sys.exc_clear too to clear the exception just before 17 # allowing .join() to return. 18 #XXX __exc_clear = _sys.exc_clear 19 20 def __init__(self, group=None, target=None, name=None, 21 args=(), kwargs=None, *, daemon=None): 22 """This constructor should always be called with keyword arguments. Arguments are: 23 24 *group* should be None; reserved for future extension when a ThreadGroup 25 class is implemented. 26 27 *target* is the callable object to be invoked by the run() 28 method. Defaults to None, meaning nothing is called. 29 30 *name* is the thread name. By default, a unique name is constructed of 31 the form "Thread-N" where N is a small decimal number. 32 33 *args* is the argument tuple for the target invocation. Defaults to (). 34 35 *kwargs* is a dictionary of keyword arguments for the target 36 invocation. Defaults to {}. 37 38 If a subclass overrides the constructor, it must make sure to invoke 39 the base class constructor (Thread.__init__()) before doing anything 40 else to the thread. 41 42 """ 43 assert group is None, "group argument must be None for now" 44 if kwargs is None: 45 kwargs = {} 46 self._target = target 47 self._name = str(name or _newname()) 48 self._args = args 49 self._kwargs = kwargs 50 if daemon is not None: 51 self._daemonic = daemon 52 else: 53 self._daemonic = current_thread().daemon 54 self._ident = None 55 self._tstate_lock = None 56 self._started = Event() 57 self._is_stopped = False 58 self._initialized = True 59 # sys.stderr is not stored in the class like 60 # sys.exc_info since it can be changed between instances 61 self._stderr = _sys.stderr 62 # For debugging and _after_fork() 63 _dangling.add(self) 64 def run(self): 65 """Method representing the thread's activity. 66 67 You may override this method in a subclass. The standard run() method 68 invokes the callable object passed to the object's constructor as the 69 target argument, if any, with sequential and keyword arguments taken 70 from the args and kwargs arguments, respectively. 71 72 """ 73 try: 74 if self._target: 75 self._target(*self._args, **self._kwargs) 76 finally: 77 # Avoid a refcycle if the thread is running a function with 78 # an argument that has a member that points to the thread. 79 del self._target, self._args, self._kwargs
在我上传的代码中可以看出在init方法中target参数其实就是传进去的线程,然后将target赋值到了self.target
在run方法中可以看出就是执行的这个线程
所以我们如果需要用到多线程的话直接重写run方法即可
下面来举个栗子:
from threading import Thread class MyThreading(Thread): def run(self): for i in range(1000): print("-----这是我创建的第一个线程-------") class MyThreading_2(Thread): def run(self): for i in range(1000): print("-------这是我创建的第二个线程--------") if __name__ == '__main__': a = MyThreading() b = MyThreading_2() a.start() b.start()
上面就实现了两个线程之间并发
------------------------------------------纯属个人理解,如有问题请大家指正-----------------------------------