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实现各种排序算法的代码示例总结
Dec 11 Python
Python实现简易端口扫描器代码实例
Mar 15 Python
python re正则匹配网页中图片url地址的方法
Dec 20 Python
Python调用C语言的实现
Jul 26 Python
Python终端输出彩色字符方法详解
Feb 11 Python
解决ROC曲线画出来只有一个点的问题
Feb 28 Python
Python3.9 beta2版本发布了,看看这7个新的PEP都是什么
Jun 10 Python
tensorflow 2.1.0 安装与实战教程(CASIA FACE v5)
Jun 30 Python
用Python 爬取猫眼电影数据分析《无名之辈》
Jul 24 Python
Python连接Mysql进行增删改查的示例代码
Aug 03 Python
解决Python import .pyd 可能遇到路径的问题
Mar 04 Python
python 远程执行命令的详细代码
Feb 15 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
不用mod_rewrite直接用php实现伪静态化页面代码
2008/10/04 PHP
php 远程图片保存到本地的函数类
2008/12/08 PHP
解析php session_set_save_handler 函数的用法(mysql)
2013/06/29 PHP
php下pdo的mysql事务处理用法实例
2014/12/27 PHP
php使用Image Magick将PDF文件转换为JPG文件的方法
2015/04/01 PHP
PHP的邮件群发系统phplist配置方法详细总结
2016/03/30 PHP
phpstudy后门rce批量利用脚本的实现
2019/12/12 PHP
javascript中setAttribute()函数使用方法及兼容性
2015/07/19 Javascript
jQuery实现花式轮播之圣诞节礼物传送效果
2016/12/25 Javascript
BootStrap实现轮播图效果(收藏)
2016/12/30 Javascript
深入理解AngularJS中的ng-bind-html指令
2017/03/27 Javascript
Ajax异步文件上传与NodeJS express服务端处理
2017/04/01 NodeJs
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
2018/01/25 Javascript
vue异步加载高德地图的实现
2018/06/19 Javascript
vue单页应用在页面刷新时保留状态数据的方法
2018/09/21 Javascript
微信小程序-可移动菜单的实现过程详解
2019/06/24 Javascript
JS如何操作DOM基于表格动态展示数据
2020/10/15 Javascript
python判断windows系统是32位还是64位的方法
2015/05/11 Python
利用python批量修改word文件名的方法示例
2017/10/17 Python
wxPython实现窗口用图片做背景
2018/04/25 Python
django输出html内容的实例
2018/05/27 Python
python实现将文件夹下面的不是以py文件结尾的文件都过滤掉的方法
2018/10/21 Python
Python生成器的使用方法和示例代码
2019/03/04 Python
PyCharm下载和安装详细步骤
2019/12/17 Python
基于nexus3配置Python仓库过程详解
2020/06/15 Python
Python列表的深复制和浅复制示例详解
2021/02/12 Python
VIVOBAREFOOT赤脚鞋:让您的脚做自然的事情
2017/06/01 全球购物
EJB的角色和三个对象
2015/12/31 面试题
中学生爱国演讲稿
2013/12/31 职场文书
回门宴父母答谢词
2014/01/26 职场文书
协议书与合同的区别
2014/04/18 职场文书
2015届大学生就业推荐表自我评价
2014/09/27 职场文书
试用期工作表现自我评价
2015/03/06 职场文书
拖欠货款起诉状
2015/05/20 职场文书
红色电影观后感
2015/06/18 职场文书