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 list 合并连接字符串的方法
Mar 09 Python
Python实现简单拆分PDF文件的方法
Jul 30 Python
Python线程创建和终止实例代码
Jan 20 Python
在Pycharm中项目解释器与环境变量的设置方法
Oct 29 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
Jul 15 Python
Python利用requests模块下载图片实例代码
Aug 12 Python
python根据多个文件名批量查找文件
Aug 13 Python
基于Python3.6中的OpenCV实现图片色彩空间的转换
Feb 03 Python
Python对称的二叉树多种思路实现方法
Feb 28 Python
对Python中 \r, \n, \r\n的彻底理解
Mar 06 Python
python 判断txt每行内容中是否包含子串并重新写入保存的实例
Mar 12 Python
jupyter notebook插入本地图片的实现
Apr 13 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
全国FM电台频率大全 - 2 天津市
2020/03/11 无线电
全国FM电台频率大全 - 11 浙江省
2020/03/11 无线电
如何使用脚本模仿登陆过程
2006/11/22 PHP
PHP不用第三变量交换2个变量的值的解决方法
2013/06/02 PHP
Nginx实现反向代理
2017/09/20 Servers
PHP pthreads v3下worker和pool的使用方法示例
2020/02/21 PHP
ASP SQL防注入的方法
2008/12/25 Javascript
JavaScript关于select的相关操作说明
2010/01/13 Javascript
function foo的原型与prototype属性解惑
2010/11/19 Javascript
JavaScript通过setTimeout实时显示当前时间的方法
2015/04/16 Javascript
JQuery控制Radio选中方法分析
2015/05/29 Javascript
浅析JavaScript中的事件机制
2015/06/04 Javascript
理解javascript中Map代替循环
2016/02/26 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
2017/07/22 jQuery
AngularJS动态添加数据并删除的实例
2018/02/27 Javascript
JQuery元素快速查找与操作
2018/04/22 jQuery
10个最受欢迎的 JavaScript框架(推荐)
2019/04/24 Javascript
JS实现鼠标按下拖拽效果
2020/07/23 Javascript
为什么推荐使用JSX开发Vue3
2020/12/28 Vue.js
python字典序问题实例
2014/09/26 Python
Python设计模式之代理模式简单示例
2018/01/09 Python
Python lxml解析HTML并用xpath获取元素的方法
2019/01/02 Python
pyqt5与matplotlib的完美结合实例
2019/06/21 Python
python 设置xlabel,ylabel 坐标轴字体大小,字体类型
2019/07/23 Python
python两个_多个字典合并相加的实例代码
2019/12/26 Python
Python urllib库如何添加headers过程解析
2020/10/05 Python
matplotlib之多边形选区(PolygonSelector)的使用
2021/02/24 Python
英国家喻户晓的折扣商场:TK Maxx
2017/05/26 全球购物
英国鲜花速递:Serenata Flowers
2018/04/03 全球购物
巴西24小时在线药房:Drogasil
2020/06/20 全球购物
招聘与培训专员岗位职责
2014/01/30 职场文书
学生考试舞弊检讨书
2015/01/01 职场文书
村党组织公开承诺书
2015/04/30 职场文书
小学五年级(说明文3篇)
2019/08/13 职场文书
nginx反向代理时如何保持长连接
2021/03/31 Servers
详细介绍python类及类的用法
2021/05/31 Python