Python的Thread模块学习

前言:

对于除了主线程外的子线程来说,只有两种方法可以明确一个线程活动,传递一个回调函数给构造函数(直接传入要运行的方法),或者在子类中覆盖run方法。换句话说在Thread的子类中,只有run()和__init__()方法可以覆盖 。

主线程


当一个进程启动之后,会默认产生一个主线程。main()函数启动一个进程进而产生一个主线程。

子线程


通过Threading模块的Thread()类新生成的示例,传入一个要运行的方法,或者覆盖改写子类中的run()方法来生成新线程。

主线程,子线程的关系


  • 当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在python中,默认情况下(其实就是setDaemon(False)),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束,例子见下面一。
  • 当我们使用setDaemon(True)方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止,例子见下面二。
  • 当我们使用join()时,join所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态,主线程一直等待全部的子线程结束之后,主线程自身才结束,程序退出。
    [t.join() for t in threads ]

socket.accept() & recv()方法


  • socket.accept( )阻塞线程的方法,如果没有accept,就一直阻塞线程。
  • socket.recv( )阻塞线程的方法,如果没有收到消息就一直阻塞线程

socket的Server端和Client端交流(send &recv)


  • 服务端必须生成多个ClientTheread来应对不同的客户端建立的连接,因为(conn,(ip,port)) = tcpServer.accept(),即一个客户端的连接,socket.accept()就返回一个 (conn,(ip,port))data = conn.recv(1024)用来接受客户端发送过来的消息data.decode("utf-8")来解码,conn.send(text.encode("utf-8"))用来向客户端编码并发送消息。
  • 一个客户端只用生成一个socket对象A,然后A.connect()之后就可以A.recv(1024)来接收服务器发送过来的数据,通过tcpClientA.send(text.encode("utf-8"))来向服务端发送编码好的消息。

线程生成方法


  • 通过将要运行的代码编写为一个函数,然后将函数传入线程的初始化(即构造函数)表达式中
  • 实例一个线程对象,然后调用start方法,start方法会激活run方法进而执行run方法里的任务或行为。
newthread = ClientThread(ip,port,window)
newthread.start()

Thread对象


Once a thread object is created, its activity must be started by calling the thread’s start() method. This invokes the run() method in a separate thread of control.

  • 主线程。
  • 通过主线程来创造其他的子线程。
  • 线程n。
  • 线程没有terminate()函数(与进程的区别)。

猜你喜欢

转载自blog.csdn.net/qq_28485501/article/details/84944881