1 线程threading

1.1 基本概述

也被称为轻量级的进程。

线程是计算机多任务编程的一种方式,可以使用计算机的多核资源。

线程死应用程序中工作的最小单元

1.2 线程特点

(1)进程的创建开销较大,线程创建开销较小

(2)一个进程中可以包含多个线程

(3)线程依附于进程的存在,多个线程共享进程的资源

(4)每个线程也拥有自己独特的特征,比如ID、指令集

注意:

(1)进程有独立的空间,数据安全性较高

(2)线程使用进程的资源,即一般使用全局变量的方式进行线程间通信,所以需要较复杂的同步互斥

(3)多个不相关的线程功能最好不要凑到一起形成线程

1.3 线程与进程

(1)进程是线程的容器,一个程序的执行实例就是一个进程,线程是进程的实际运作单位。

(2)进程是系统进行资源分配调度的基本单元,是操作系统结构的基础;线程是操作系统能够运算调度的最小单位。

(3)进程之间是相互隔离的,即一个进程既无法访问其他进程的内容,也无法操作其他进程,而操作系统会跟踪所有正在运行的进程,给每个进程一小段运行时间,然后切换到其他进程。

(4)python的线程没有优先级,没有线程组的概念,也不能被销毁、停止、挂起,自然也没有恢复、中断。 

2 线程模块

Thread module emulating a subset of Java's threading model

2.1 线程模块之类

Thread,Event, Lock, Rlock, Condition, [Bounded]Semaphore, Timer, local。

2.2 线程模块之方法属性

方法:

threading.current_thread():返回当前的线程变量。

threading.active_count():

threading.stack_size()

threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

threading.setprofile(func)

threading.Lock()

threading.Rlock()

属性:

t = threading.Thread(target=function),t为线程实例

t.name:线程的名称

t.getName:获得线程名字

t.is_alive:获取线程的状态

2.3 线程模块之常量

threading.TIMEOUT_MAX 设置threading全局超时时间。

3 Thread类

3.1 Thread类

class Thread(builtins.object)的Methods defined here:

Thread(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)

group:线程组,目前没有实现,为了将来实现ThreadGroup类的扩展而设置的。

target:要执行的方法,run()方法调用的对象

name:线程名,在默认情况下,命名为Thread-N(N为最小的十进制数字)

args:元组参数

kwargs:字典参数

3.2 Thread类的实例方法:

start():启动线程

join(self, timeout=None):等待线程结束,阻塞线程直到调用此方法的线程终止或到达指定的的timeout

is_alive():返回线程是否在运行,运行返回True;

isAlive:等价于is_alive()

getName():获取线程名字

setName():设置线程名字,在threading.Thread()的帮助文档中没有该方法,其他资料上有。

is/setDaemon(bool): 获取/设置是后台线程(默认前台线程(False))。(在start之前设置)

  如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,主线程和后台线程均停止
       如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止

3.3 线程的创建方法

线程的创建方法有两种

一种是利用threading.Thread()直接创建线程

import threading
import time

def music(sec):
    print('播放音乐')
    time.sleep(sec)

t = threading.Thread(name='createthread',target=music,args=(2,))

t.start()

print("结束!")

运行

播放音乐
结束!

另外是利用 threading.Thread() 类的继承、并重写 run() 来创建线程

import threading
import time

class MyThread(threading.Thread):
    def __init__(self,arg):
        # 注意:一定要显式的调用父类的初始化函数。
        super(MyThread, self).__init__()
        self.arg=arg

    # 定义每个线程要运行的函数
    def run(self):
        time.sleep(1)
        print('the arg is:%s\r' % self.arg)

for i in range(3):
    t =MyThread(i)
    t.start()

print('main thread end!')

运行

main thread end!
the arg is:0
the arg is:1
the arg is:2

3.4 线程传参

事实上:线程传参与函数传参没有明显区别,本质上就是函数传参

import threading

def add(x, y):
    print('{} + {} = {}'.format(x, y, x + y, threading.current_thread()))

# 创建线程对象
thread1 = threading.Thread(target=add, name='add', args=(4, 5))
thread2 = threading.Thread(target=add, name='add', args=(4,), kwargs={'y': 5})
thread3 = threading.Thread(target=add, name='add', kwargs={'x': 4, 'y': 5})

# 启动线程
thread1.start()
thread2.start()
thread3.start()

运行

4 + 5 = 9
4 + 5 = 9
4 + 5 = 9

关于format函数参看 python的format函数python中强大的format函数

3.5 线程中的变量

import threading
import time

a = 10

def music(sec):
    print('播放音乐')
    print(a)
    time.sleep(sec)
    print(a)

t = threading.Thread(name='mythread',target=music,args=(2,))

t.start()

print("------------main--------------")
time.sleep(2)
a = 100

运行

# 第一次运行
播放音乐
10
------------main--------------
100
# 第二次运行
播放音乐
10
------------main--------------
10

说明:

(1)同一个程序,运行后的结果不相同,因为在同样sleep(2)后,全局变量重新绑定了100,而进程最后打印出变量a,若变量a先绑定100,则会打印出100,若先打印则为10

(2)将args=(2,)变为args=(3,),则会稳定打印出100

(3)将全局变量的前的sleep(2)变为sleep(3),则结果稳定打印出10

示例2

import threading
import time

a = 10

def music1(sec):
    a = 1000
    print('m11',a)
    time.sleep(sec)
    print('m12',a)

def music2(sec):
    print('m21',a)
    time.sleep(sec)
    print('m22',a)

t1 = threading.Thread(name='mythread1',target=music1,args=(2,))
t2 = threading.Thread(name='mythread2',target=music2,args=(3,))

t1.start()
t2.start()

print("------------main--------------")
# time.sleep(2)
a = 100

运行

m11 1000
------------main--------------
m21 10
m12 1000
m22 100

3.6 线程中的属性方法

import threading
import time

def music(sec):
    print('播放音乐')
    time.sleep(sec)

t = threading.Thread(name='mythread',target=music,args=(2,))

t.start()

print('name:',t.name)#线程名称
t.setName("yourthread")#设置线程的名称

print('name:',t.name)#线程名称
print('getName:',t.getName())# 获得线程名称
print('is_alive:',t.is_alive()) #获取线程状态

t.join()#阻塞等待进程退出
print("------------main--------------")

运行

播放音乐
name: mythread
name: yourthread
getName: yourthread
is_alive: True
------------main--------------

3.7 在本地计算机上可以创建线程的最大数量

# 查看可以创建多少线程
# 可以用top查看CPU运行情况
import threading
import time

a = 0

def music(sec):
    global a
    a += 1
    time.sleep(sec)
    print(a)
    # 阻塞创建的线程退出
    while True:
        pass

thread_list = []
while True:
    t = threading.Thread(target=music,args=(2,))
    t.start() #启动线程
    thread_list.append(t)

for i in thread_list:
    i.join()#阻塞等待线程退出

数据显示,可以创建2961个线程,同时在新的终端上top查看CPU运行达到100%

相关参考:

python 并发和线程

python--threading多线程总结

python并发编程之多线程

python学习笔记——线程threading (一)的更多相关文章

  1. python学习笔记——线程threading (二)重写run()方法和守护进程daemon()

    1 run()方法 1.1 单个线程 在threading.Thread()类中有run()方法. from time import ctime,sleep import threading # 定义 ...

  2. python学习笔记(threading接口性能压力测试)

    又是新的一周 延续上周的进度 关于多进程的学习 今天实践下 初步设计的接口性能压力测试代码如下: #!/usr/bin/env python # -*- coding: utf_8 -*- impor ...

  3. python学习笔记(threading多线程)

    博主昨天优化了接口框架想着再添加些功能 想到对接口的性能压力测试 在工作过程中之前都是使用的工具 如:loadrunner.jmeter 想着这次准备用python实现对接口的性能压力测试 首先要实现 ...

  4. OpenCV之Python学习笔记

    OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书< ...

  5. Python学习笔记进阶篇——总览

    Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(Socket编程进阶&多线程.多进程) Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(异常处理) Pyth ...

  6. Python学习笔记基础篇——总览

    Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...

  7. Python学习笔记(十一)

    Python学习笔记(十一): 生成器,迭代器回顾 模块 作业-计算器 1. 生成器,迭代器回顾 1. 列表生成式:[x for x in range(10)] 2. 生成器 (generator o ...

  8. Python学习笔记,day5

    Python学习笔记,day5 一.time & datetime模块 import本质为将要导入的模块,先解释一遍 #_*_coding:utf-8_*_ __author__ = 'Ale ...

  9. python学习笔记目录

    人生苦短,我学python学习笔记目录: week1 python入门week2 python基础week3 python进阶week4 python模块week5 python高阶week6 数据结 ...

随机推荐

  1. 告诉我, 究竟我的SQL Server慢在哪里?

    你可以使用下面的语句来使用sys.dm_os_wait_stats这个DMV得到线程的等待信息(线程在等什么, 等了多久)的统计数值. WITH [Waits] AS (SELECT [wait_ty ...

  2. js常用的事件对象

    事件源对象  event.srcElement.tagName  event.srcElement.type 捕获释放  event.srcElement.setCapture();   event. ...

  3. 在web项目启动时执行某个方法

    在web项目中有很多时候需要在项目启动时就执行一些方法,而且只需要执行一次,比如:加载解析自定义的配置文件.初始化数据库信息等等,在项目启动时就直接执行一些方法,可以减少很多繁琐的操作. 在工作中遇到 ...

  4. Android -- Fragment动画异常Unknown animation name: objectAnimator

    异常 Caused by: java.lang.RuntimeException: Unknown animation name: objectAnimator 异常代码 FragmentTransa ...

  5. ComboBoxEdit 数据绑定 使用模板

    1)定义模板资源 <UserControl.Resources> <local:StatusConvertor x:Key="StatusConvertor"&g ...

  6. [Webpack] Externalize Dependencies to be Loaded via CDN with webpack

    We can separate our custom application code from the common libraries we leverage, such as React and ...

  7. Linux:su和su-的区别

    大部分Linux发行版的默认账户是普通用户,而更改系统文件或者执行某些命令,需要root身份才能进行,这就需要从当前用户切换到root用户.Linux中切换用户的命令是su或su -. 如上图所示,一 ...

  8. 【iOS】网络操作与AFNetworking

    众所周知.苹果搞的一套框架NSContention发送请求与接收请求的方式十分繁琐.操作起来非常不方便. 不仅要做区分各种请求设置各种不同的參数,并且还要常常在多线程里操作,同一时候还要对请求与返回的 ...

  9. freemarker 模板开发入门

    数据模型 scalars标量:从根 root 開始指定它的路径,每级之间用点来分隔. 如:whatnot.fruits sequences 序列:使用数组的方括号方式来訪问一个序列的子变量. 如:an ...

  10. Windows 之 防火墙

          对于只使用浏览.电子邮件等系统自带的网络应用程序,Windows防火墙(firewall)根本不会产生影响.也就是说,用IE.OutlookExpress等系统自带的程序进行网络连接,防火 ...