线程 threading模块

线程

什么是线程

  • 线程是计算机中被cpu调度的最小单位
  • cpu都是执行的线程中的代码
  • 线程被包含在进程中 ,是进程的实际运作单位

60年代,在OS中能拥有资源和独立运行的基本单位是进程,然而随着计算机技术的发展,进程出现了很多弊端,一是由于进程是资源拥有者,创建、撤消与切换存在较大的时空开销,因此需要引入轻型进程;二是由于对称多处理机(SMP)出现,可以满足多个运行单位,而多个进程并行开销过大。

  因此在80年代,出现了能独立运行的基本单位——线程(Threads)

  注意:进程是资源分配的最小单位,线程是CPU调度的最小单位.

     每一个进程中至少有一个线程。 

线程和进程之间的关系

观看图解

线程与进程的区别可以归纳为以下4点:

  1)地址空间和其它资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。

  2)通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。

  3)调度和切换:线程上下文切换比进程上下文切换要快得多。

  4)在多线程操作系统中,进程不是一个可执行的实体。

一个进程中的多个线程能够并行么?

  不行 因为Cpython中有一把全局解释器锁,GIL 所以所线程不能充分利用多核,

  同一时刻用一个进程中的线程只有一个能被CPU执行

  GIL锁 确实是限制了你的程序效率

  GIL锁目前是能够帮助你在线程中的切换中提高效率

内存中的线程

多个线程共享同一个进程的地址空间中的资源,是对一台计算机上多个进程的模拟,有时也称线程为轻量级的进程。

  而对一台计算机上多个进程,则共享物理内存、磁盘、打印机等其他物理资源。多线程的运行也多进程的运行类似,是cpu在多个线程之间的快速切换。

  不同的进程之间是充满敌意的,彼此是抢占、竞争cpu的关系,如果迅雷会和QQ抢资源。而同一个进程是由一个程序员的程序创建,所以同一进程内的线程是合作关系,一个线程可以访问另外一个线程的内存地址,大家都是共享的,一个线程干死了另外一个线程的内存,那纯属程序员脑子有问题。

  类似于进程,每个线程也有自己的堆栈,不同于进程,线程库无法利用时钟中断强制线程让出CPU,可以调用thread_yield运行线程自动放弃cpu,让另外一个线程运行。

  线程通常是有益的,但是带来了不小程序设计难度,线程的问题是:

  1. 父进程有多个线程,那么开启的子线程是否需要同样多的线程

  2. 在同一个进程中,如果一个线程关闭了文件,而另外一个线程正准备往该文件内写内容呢?

  因此,在多线程的代码中,需要更多的心思来设计程序的逻辑、保护程序的数据。


threading模块

创建线程

def func(i):
    print(‘子线程 :‘,i,os.getpid())

print(‘主线程 :‘,os.getpid())
for i in range(10):
    t = Thread(target=func,args=(i,))
    t.start()

Thread实例对象的方法

  • isAlive() :返回线程是否活动的
  • getName() : 返回线程名
  • setName() : 设置线程名
from threading import currentThread
def func():
    time.sleep(3)

t = Thread(target=func)
t.start()
print(t.is_alive())
print(t.getName())
t.setName(‘t1‘)
print(t.getName())
threading模块提供的一些方法:(不常用)
  threading.currentThread(): 返回当前的线程变量。
m threading import currentThread
def func():
    print(‘子线程 : ‘,currentThread().name) #返回线程名
    time.sleep(3)

print(‘主线程 : ‘,currentThread().ident) #返回线程地址
t = Thread(target=func)
t.start()
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
from threading import currentThread
from threading import enumerate
def func():
    print(‘子线程 : ‘,currentThread().ident)
    time.sleep(3)

print(‘主线程 : ‘,currentThread().ident)
for i in range(10):
    t = Thread(target=func)
    t.start()
print(len(enumerate()))
  threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
from threading import currentThread
from threading import activeCount
def func():
    print(‘子线程 : ‘,currentThread().ident)
    time.sleep(3)

print(‘主线程 : ‘,currentThread().ident)
for i in range(10):
    t = Thread(target=func)
    t.start()
print(activeCount())

守护线程

无论是进程还是线程,都遵循:守护者会等待主程序运行完毕后被销毁。需要强调的是:运行完毕并非终止运行

  • 对主进程来说,运行完毕指的是主进程代码运行完毕
  • 对主线程来说,运行完毕指的是主线程所在的程序内所有的非守护线程全部运行完毕,主线程才算运行完毕
主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,
主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。

方法一

time
from threading import Thread
def func1():
    while True:
        time.sleep(0.5)
        print(123)

def func2():
    print(‘func2 start‘)
    time.sleep(3)
    print(‘func2 end‘)

t1 = Thread(target=func1)
t2 = Thread(target=func2)
t1.setDaemon(True)  #添加守护线程
t1.start()
t2.start()
print(‘主线程的代码结束‘)

方法二

from threading import Thread
import time
def foo():
    print(123)
    time.sleep(1)
    print("end123")

def bar():
    print(456)
    time.sleep(3)
    print("end456")

t1=Thread(target=foo)
t2=Thread(target=bar)

t1.daemon=True
t1.start()
t2.start()
print("main-------")


线程 threading模块

原文地址:https://www.cnblogs.com/qq752059037/p/9699750.html

时间: 2024-10-10 12:36:50

线程 threading模块的相关文章

进程 线程 threading模块

# 进程:本质上就是一个程序在一个数据集上的一次动态执行过程(抽象的概念) # 进程一般由程序.数据集(程序运行过程中所需要使用的资源).进程控制块(记录进程的外部特征,描述进程的执行变化过程)三部分组成 # 进程是最小的资源单位 # 线程的出现是为了降低上下文切换的消耗,提高系统的并发性,并突破一个进程只能干一样事的缺陷,使到进程内并发成为可能# 线程:是最小的执行单位 # 进程与线程的联系与区别 # 1.一个程序至少有一个进程,一个进程至少有一个线程 (进程可以理解成线程的容器) # 2.进

python 线程 threading模块

# 进程 : 数据隔离,资源分配的最小单位,可以利用多核,操作系统调度,数据不安全,开启关闭切换时间开销大 # multiprocessing 如何开启进程 start join # 进程有数据不安全的问题 Lock (抢票的例子) # 进程之间可以通信ipc: # 队列(安全) 管道(不安全) # 生产者消费者模型 # 第三方工具 # 进程之间可以通过Manager类实现数据共享(不需要会写代码) # 一般情况下我们开启的进程数不会超过cpu个数的两倍# 线程(80%) # 什么是线程 :能被

python多线程与threading模块

python多线程与_thread模块 中介绍了线程的基本概念以及_thread模块的简单示例.然而,_thread模块过于简单,使得我们无法用它来准确地控制线程,本文介绍threading模块,它提供了更强大的多线程管理方案. threading模块的对象 Thread 表示一个执行线程的对象 Lock 锁原语 RLock 可重入锁对象,使单一线程可以再次获得已持有的锁(递归锁) Condition 条件变量对象,使得一个线程等待另一个线程满足特定条件 Event 条件变量的通用版本,任意数量

Python:线程、进程与协程(2)——threading模块(1)

上一篇博文介绍了Python中线程.进程与协程的基本概念,通过这几天的学习总结,下面来讲讲Python的threading模块.首先来看看threading模块有哪些方法和类吧. 主要有: Thread :线程类,这是用的最多的一个类,可以指定线程函数执行或者继承自它都可以实现子线程功能. Timer:与Thread类似,但要等待一段时间后才开始运行,是Thread的子类. Lock :原锁,是一个同步原语,当它锁住时不归某个特定的线程所有,这个可以对全局变量互斥时使用. RLock :可重入锁

python全栈开发基础【第二十四篇】(利用threading模块开线程、join与守护线程、GIL与Lock)

一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 创建线程的开销比创建进程的开销小,因而创建线程的速度快. #开启进程的第一种方式 from multiprocessing import Process from threading import Thread import os import time def work(): print('<%s> is running'%os.g

第36篇 多进程的数据共享,进程池的回调函数,线程 什么是GIL锁,Threading模块记

内容概览: 进程 数据共享 进程池--回调函数 线程 线程的基础理论 什么是线程? 线程与进程的关系 GIL锁 线程的开启: Threading模块1,用多进程开启socket创建聊天 server端写了input函数会报错?因为服务器是高速运行的,自动化的为来访问的客户端提供服务, 不可能停下来等待管理员的输入,然后发送给客户.这就失去了自动化的意义. 2,进程池Pool()方法创建的进程,map()方法是否有返回值? p.map()得到的是迭代对象 import time from mult

利用threading模块开线程

一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 1 1.创建线程的开销比创建进程的开销小,因而创建线程的速度快 2 from multiprocessing import Process 3 from threading import Thread 4 import os 5 import time 6 def work(): 7 print('<%s> is running'%o

利用threading模块开线程方法

一多线程的概念介绍threading模块介绍threading模块和multiprocessing模块在使用层面,有很大的相似性.二.开启多线程的两种方式1.创建线程的开销比创建进程的开销小,因而创建线程的速度快from multiprocessing import Processfrom threading import Threadimport osimport timedef work():print('<%s> is running'%os.getpid())time.sleep(2)

threading 模块

threading模块里面主要是对一些线程的操作对象化了,创建了Thread class.使用线程有两种模式,一种是创建线程要执行的 函数,把这个函数传递进Thread对象里,让它来执行:另一种是直接从Thread继承,创建一个新的class,把线程执行的代码放到这个新的 class里. 1 __author__ = 'Zechary' 2 import string, threading, time 3 def thread_main(a): 4 global count, mutex 5 t