python程序 创建多线程过程详解


Posted in Python onSeptember 23, 2019

一、python线程的模块

1.1 thread和threading模块

thread模块提供了基本的线程和锁的支持

threading提供了更高级别、功能更强的线程管理的功能。

1.2 Queue模块

Queue模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。

1.3注意模块的选择

  • 避免使用thread模块
  • 因为更高级别的threading模块更为先进,对线程的支持更为完善
  • 而且使用thread模块里的属性有可能会与threading出现冲突;
  • 其次低级别的thread模块的同步原语很少(实际上只有一个),而threading模块则有很多;
  • 再者,thread模块中当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作,至少threading模块能确保重要的子线程退出后进程才退出。

注意:thread模块不支持守护线程,当主线程退出时,所有的子线程不论它们是否还在工作,都会被强行退出。而threading模块支持守护线程,守护线程一般是一个等待客户请求的服务器,如果没有客户提出请求它就在那等着,如果设定一个线程为守护线程,就表示这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。

二、Threading模块

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

三、通过Threading.Thread类来创建线程

3.1 创建线程的方式一

1.直接通过Threading.Thread来创建

from threading import Thread
import time

def task(name):
  print(f'子线程{name} is running')
  time.sleep(1)
  print(f'子线程{name} is end')
  
# 因为创建线程不需要重新开辟内存空间,所以不用写main,创建线程只是单独把启动线程函数里面的代码拿出来用
t = Thread(target=task,args=('Cecilia陈',))
t.start()
print('主线程结束')

子线程Cecilia陈 is running

主线程结束

子线程Cecilia is end

3.2 创建线程的方式二

2.通过自定义类来继承Thread类来创建线程

from threading import Thread
import time
class MyDic(Thread,name):
  def __init__(self,name)
    super().__init__()
    self.name = name
  def run(self):
    print(f'子线程{name} is running')
    time.sleep(1)
    print(f'子线程{name} is end')
t = Mydic('Cecilia陈')
t.start()
print('主进程结束')

线程Cecilia陈 start

主进程

线程Cecilia陈 end

四、多线程和多进程的比较

4.1 pid的比较

from threading import Thread
from multiprocessing import Process
import time
import os

def task(name):
  print(f'子线程{name} is running')
  time.sleep(1)
  print(f'子线程{name} is end')
  print(f'子线程{name}的pid:{os.getpid()}')
def task1(name):
  print(f'进程{name} is running')
  time.sleep(1)
  print(f'进程{name} is end')
  print(f'进程的{name}pid:{os.getpid()}')
if __name__ == '__main__':
  # part1:在主进程下开启多个线程,每个线程都跟主进程的pid一样
  t = Thread(target=task, args=('Cecilia陈',))
  t.start()
  t.join()
  print(f'主线程的pid:{os.getpid()}')
  # 开多个进程,每一个进程的pid号都不一样
  p = Process(target=task1,args=('xichen',))
  p1 = Process(target=task1,args=('xixi',))
  p.start()
  p1.start()
  p.join()
  p1.join()
  print(f'主进程的pid:{os.getpid()}')

子线程Cecilia陈 is running
子线程Cecilia陈 is end
子线程Cecilia陈的pid:10892
主线程的pid:10892
进程xixi is running
进程xichen is running
进程xichen is end
进程xixi is end
进程的xichenpid:6844
进程的xixipid:13700
主进程的pid:10892

4.2 线程和进程开启效率的较量

from threading import Thread
from multiprocessing import Process
import time
def task(name):
  print(f'{name} is running')
  time.sleep(2)
  print(f'{name} is end')
if __name__ == '__main__':
  t = Thread(target=task,args=('子线程',))
  p = Process(target=task,args=('子进程',))
  t.start()
  # p.start()
  print('主')

1.开启线程的速度:

子线程 is running

子线程 is end

2.开启进程的速度:

子进程 is running

子进程 is end

4.3 内存数据共享问题

from threading import Thread
from multiprocessing import Process
import time,os
x = 100
def task():
  global x
  x = 50 # 此时线程是在拿全局的x的值
  print(os.getpid()) # 因为开启线程是不需要操作系统给线程分配内存空间的,所以线程用的是它当前所在的进程的进程号
if __name__ == '__main__':
  # 线程
  t = Thread(target=task)
  t.start()
  time.sleep(2)
  print(x) # 50,这里说明线程他是共享他所在进程下的所有资源,对资源进行一系列的操作
  print(os.getpid())
  # 进程
  # p = Process(target=task)
  # p.start() 
  # print(x) # 这里的x还是主进程的x 100

五、Thread类的其他方法

Thread实例对象的方法:

  • isAlive():返回线程是否活动的。
  • getName():返回线程名。
  • setName():设置线程名。

threading模块提供的一些方法:

  • threading.currentThread():返回当前的线程变量。
  • threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  • threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

5.1 代码实例

from threading import Thread,currentThread,enumerate,activeCount
import time

def task():
  print('子线程 start')
  time.sleep(2)
  print('子线程 end')
  print(enumerate())# 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  print(currentThread(),'子线程') # 返回当前的线程变量
  print(activeCount())

if __name__ == '__main__':
  t1 = Thread(target=task)
  t2 = Thread(target=task)
  t1.start()
  t2.start()
  t2.setName('Cecilia陈')
  print(t2.getName()) # 得到t2的线程名字,是我们设置好的Cecilia陈
  print(t1.getName()) # 得到t1的线程名子 Thread-1
  print(t1.is_alive()) # True

5.2 join方法

from threading import Thread
import time
def task():
  print('子线程 start')
  time.sleep(2)
  print('子线程 end')

t = Thread(target=task)
t.start()
t.join() # 等待子线程运行结束
print('主线程')

六、多线程实现socket

6.1 服务端

import socket
from threading import Thread

socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket.bind(('192.168.11.78',8004))
socket.listen(5)

def action(conn,addr):
  while True:
    try:

      msg = (conn.recv(1024)).decode('utf8').upper()
      print(f'客户端{addr}发送的数据为:{msg.lower()}')
      print(f'向客户端{addr}发送数据为',msg)
      conn.send(msg.encode('utf8'))
    except:
      break
if __name__ == '__main__':
  print('等待客户端连接:')
  while True:
    try:
      conn,addr = socket.accept()
      print(f'客户端已连接{addr}')
      t = Thread(target=action,args=(conn,addr))
      t.start()
    except:
      print(f'客户端{addr}断开连接 !!')
      break

6.2 客户端

import socket
client = socket.socket()
client.connect(('192.168.11.78',8004))
while True:
  msg = input('输入:')
  if msg == 'q':
    break
  client.send(msg.encode('utf8'))
  flag = client.recv(1024)
  print('接收服务端的数据为:',flag.decode('utf8'))

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python自动化测试之setUp与tearDown实例
Sep 28 Python
使用beaker让Facebook的Bottle框架支持session功能
Apr 23 Python
Python实现OpenCV的安装与使用示例
Mar 30 Python
python文件操作之批量修改文件后缀名的方法
Aug 10 Python
浅谈Django的缓存机制
Aug 23 Python
浅谈python3发送post请求参数为空的情况
Dec 28 Python
关于阿里云oss获取sts凭证 app直传 python的实例
Aug 20 Python
基于python读取.mat文件并取出信息
Dec 16 Python
使用python把xmind转换成excel测试用例的实现代码
Oct 12 Python
Python实现给PDF添加水印的方法
Jan 25 Python
使用Python通过企业微信应用给企业成员发消息
Apr 18 Python
PYTHON基于Pyecharts绘制常见的直角坐标系图表
Apr 28 Python
详解python播放音频的三种方法
Sep 23 #Python
Python进程间通信 multiProcessing Queue队列实现详解
Sep 23 #Python
python程序中的线程操作 concurrent模块使用详解
Sep 23 #Python
Python3 pandas 操作列表实例详解
Sep 23 #Python
详解基于python-django框架的支付宝支付案例
Sep 23 #Python
如何利用Python开发一个简单的猜数字游戏
Sep 22 #Python
Python中关于浮点数的冷知识
Sep 22 #Python
You might like
destoon公司主页模板风格的添加方法
2014/06/20 PHP
php程序总是提示验证码输入有误解决方案
2015/01/07 PHP
php实现与python进行socket通信的方法示例
2017/08/30 PHP
Yii2框架可逆加密简单实现方法
2017/08/25 PHP
php+mysql开发的最简单在线题库(在线做题系统)完整案例
2019/03/30 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
php实现根据身份证获取精准年龄
2020/02/26 PHP
用JS操作FRAME中的IFRAME及其内容的实现代码
2008/07/26 Javascript
jquery select(列表)的操作(取值/赋值)
2009/08/06 Javascript
js setTimeout opener的用法示例详解
2013/10/23 Javascript
IE 下Enter提交表单存在重复提交问题的解决方法
2014/05/04 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
2016/01/26 Javascript
jquery实现自适应banner焦点图
2017/02/16 Javascript
微信小程序如何再次获取用户授权的方法
2019/05/10 Javascript
JS实现提示效果弹出及延迟隐藏的功能
2019/08/26 Javascript
vue项目部署到nginx/tomcat服务器的实现
2019/08/26 Javascript
vue开发移动端底部导航条功能
2020/04/08 Javascript
归纳整理Python中的控制流语句的知识点
2015/04/14 Python
在Python中封装GObject模块进行图形化程序编程的教程
2015/04/14 Python
使用Python的Tornado框架实现一个Web端图书展示页面
2016/07/11 Python
深入理解Python中变量赋值的问题
2017/01/12 Python
微信跳一跳辅助python代码实现
2018/01/05 Python
python utc datetime转换为时间戳的方法
2019/01/15 Python
正确理解Python中if __name__ == '__main__'
2019/01/24 Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
2019/03/22 Python
python使用建议与技巧分享(二)
2020/08/17 Python
新百伦折扣店:Joe’s New Balance Outlet
2016/08/20 全球购物
房地产管理毕业生自荐信
2013/11/04 职场文书
拾金不昧的表扬信
2014/01/16 职场文书
期中考试后的反思
2014/02/08 职场文书
《数星星的孩子》教学反思
2014/04/11 职场文书
2014年预备党员群众路线教育实践活动对照检查材料思想汇报
2014/10/02 职场文书
2015大学生暑期实习报告
2015/07/13 职场文书
幼儿园教师管理制度
2015/08/05 职场文书
2016年大学生党员公开承诺书
2016/03/24 职场文书
MySQL去除重叠时间求时间差和的实现
2021/08/23 MySQL