进程和线程

进程和线程,多进程和多线程 进程和线程,多进程和多线程 进程和线程 (1)进程 ​ 进程就是正在运行的程序,是系统进行资源分配和调用的独立单位 (2)线程 ​ 在一个进程内部又可以执行多个任务,而这每一个任务我们就可以看成是一个线程。是程序使用CPU的基本单位。所以,进程是拥有资源的基本单位, 线程是CPU调度的基本单位。 (3)比较进程和线程 ​ 举个例子,有两个进程,一个是Word, 一个是QQ音乐。 Word 进程打开... 阅读详情

fork实现多进程

普通的方法都是调用一次,返回一次,而os的fork方法是调用一次,返回两次,原因是操作系统将当前进程(父进程)复制出一份进程(子进程),这两个进程几乎完全相同,于是fork方法分别在父进程和子进程中返回。
子进程中永远返回0,父进程中返回的是子进程的ID。

import os

if __name__ == '__main__':
    print 'current Process (%s) start ...' % (os.getpid())
    pid = os.fork()
    if pid < 0:
        print 'error in fork'
    elif pid == 0:
        print 'I am child process(%s) and my parent process is (%s)'% (os.getpid(), os.getppid())
    else:
        print 'I(%s) created a child process (%s).'%(os.getpid(), pid)

 

multiprocessing实现多进程

multiprocessing提供一个Process类来描述一个进程对象。

创建子进程时,只需要传入一个执行函数和函数的参数,即可完成一个Process实例的创建,用start()方法启动进程,用join()方法实现进程间的同步。

import os
from multiprocessing import Process

def run_proc(name):
    print 'Child process %s (%s) Running...'%(name,os.getpid())

if __name__ == '__main__':
    print 'Parent process %s.'% os.getpid()
    for i in range(5):
        p = Process(target=run_proc,args=(str(i),))
        print 'Process will start.'
        p.start()
    p.join()
    print 'Process end.'

 

通过multiprocessing提供的Pool类实现多进程

Pool可以提供指定数量的进程供用户调用,默认大小是CPU的核数。

当有新的请求提交到Pool时,如果池还没有满,就会创建一个新的进程用来执行该请求,如果池中进程数已经达到规定的量大值,请求就会等待,直到池中有进程结束,才会创建新的进程来处理它。

from multiprocessing import Pool
import os
import time
import random

def run_task(name):
    print 'Task %s (pid = %s) is running... '%(name,os.getpid())
    time.sleep(random.random()*3)
    print 'Task %s end.'%name


if __name__ == '__main__':
    print 'Current process %s.'%os.getpid()
    p = Pool(processes=3)
    for i in range(5):
        p.apply_async(run_task,args=(i,))
    print 'Waiting for all subprocesses done...'
    p.close()#必须放在join之前,调用close之后就不能继续添加新的进程
    p.join()
    print 'All subprocesses done.'

进程间通信

Pipe常用在两个进程间通信,Queue用在多进程间通信

Put和Get可以进行Queue操作

Put方法可以把数据插入到队列中,有两个可选参数:blocked和timeout

如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余空间。

如果超时,会抛出Queue.Full异常。

如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。

 

Get方法可以从队列读取并且删除一个元素,有两个可选参数:blocked和timeout。

如果blocked为True(默认值),并且timeout为正值,在等待时间内没有取到任何元素,会抛出Queue.Empty异常。

如果blocked为False,分两种情况:

1、如果Queue有一个值可用,则立即返回该值

2、如果队列为空,则立即抛出Queue.Empty异常

 

 

import os
import random
import time
from multiprocessing import Process,Queue

def proc_write(q, urls):
    print 'Process %s is writing...' % os.getpid()
    for url in urls:
        q.put(url)
        print 'Put %s to queue...' % url
        time.sleep(random.random())


def proc_read(q):
    print 'Process %s is reading...' % os.getpid()
    while True:
        url = q.get(True)
        print 'Get %s from queue.' % url


if __name__ == '__main__':
    q = Queue()
    proc_write1 = Process(target=proc_write, args=(q, ['url_1', 'url_2', 'url_3']))
    proc_write2 = Process(target=proc_write, args=(q, ['url_4', 'url_5', 'url_6']))
    proc_reader = Process(target=proc_read, args=(q,))

    proc_write1.start()
    proc_write2.start()
    proc_reader.start()
    proc_write1.join()
    proc_write2.join()
    proc_reader.terminate()

Pip方法返回(conn1,conn2)代表一个管道的两个端。

Pipe方法有duplex参数,如果duplex参数为True(默认值),这个管道是全双工模式,就是conn1和conn2均可收发。

如果duplex为False,conn1只负责接收消息,conn2只负责发送消息。

send和recv方法分别是发送和接收消息的方法。

在全双工模式下,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。

例子:

import multiprocessing
import random
import time,os


def proc_send(pipe, urls):
    for url in urls:
        print 'process (%s) send:%s'%(os.getpid(),url)
        pipe.send(url)
        time.sleep(random.random())


def proc_recv(pipe):
    while True:
        print 'process (%s) rev:%s'%(os.getpid(),pipe.recv())
        time.sleep(random.random())

if __name__ == '__main__':
    pipe = multiprocessing.Pipe()
    p1 = multiprocessing.Process(target=proc_send,args=(pipe[0],['url_'+str(i) for i in  range(10)]))
    p2 = multiprocessing.Process(target=proc_recv,args=(pipe[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

 

多线程

优点:

1、可以把运行时间长的任务放到后台去处理

2、界面可以更吸引人

3、加快程序运行速度

4、在等待任务时,可以释放一些资源

thread是低级模块,threading是高级模块,对thread进行了封装。

 

 

用threading实现多线程

第一种方式:把一个函数传入并创建Thread实例,然后调用start方法开始执行

例子:

import random
import time, threading


def thread_run(urls):
    print('Current %s is running...' % threading.current_thread().name)
    for url in urls:
        print('%s ---->>> %s' % (threading.current_thread().name, url))
        time.sleep(random.random())
    print('%s ended...' % threading.current_thread().name)


print('%s is running...' % threading.current_thread().name)
t1 = threading.Thread(target=thread_run, name='Thread_1', args=(['url_1', 'url_2', 'url_3'],))
t2 = threading.Thread(target=thread_run, name='Thread_2', args=(['url_4', 'url_5', 'url_6'],))
t1.start()
t2.start()
t1.join()
t2.join()
print('%s ended.' % threading.current_thread().name)

结果:

MainThread is running...
Current Thread_1 is running...
Thread_1 ---->>> url_1
Current Thread_2 is running...
Thread_2 ---->>> url_4
Thread_1 ---->>> url_2
Thread_2 ---->>> url_5
Thread_2 ---->>> url_6
Thread_1 ---->>> url_3
Thread_2 ended...
Thread_1 ended...
MainThread ended.

第二种方式:直接从threading.Thread继承并创建线程类,然后重写__init__和run方法

例子:

import random
import threading
import time


class myThread(threading.Thread):
    def __init__(self, name, urls):
        threading.Thread.__init__(self, name=name)
        self.urls = urls

    def run(self):
        print('Current %s is running...' % threading.current_thread().name)
        for url in self.urls:
            print('%s ---->>> %s' % (threading.current_thread().name, url))
            time.sleep(random.random())
        print('%s ended.' % threading.current_thread().name)


print('%s is running...' % threading.current_thread().name)
t1 = myThread(name='Thread_1', urls=['url_1', 'url_2', 'url_3'])
t2 = myThread(name='Thread_2', urls=['url_4', 'url_5', 'url_6'])
t1.start()
t2.start()
t1.join()
t2.join()
print('%s ended...' % threading.current_thread().name)

结果:

MainThread is running...
Current Thread_1 is running...
Thread_1 ---->>> url_1
Current Thread_2 is running...
Thread_2 ---->>> url_4
Thread_2 ---->>> url_5
Thread_1 ---->>> url_2
Thread_2 ---->>> url_6
Thread_1 ---->>> url_3
Thread_2 ended.
Thread_1 ended.
MainThread ended...

 

线程同步

如果多个线程共同修改某个数据,则可能会出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。使用Thread对象的Lock和RLock可以实现简单的线程同步,这两个对象都有acquire方法和release方法,对于那些每次只允许一个线程操作的数据,可以将其操作放到acquire和release方法之间。

对于Lock对象来说,如果一个线程连续两次进行acquire操作,那么由于第一次acquire之后没有release,第二次acquire将挂起线程。这会导致Lock对象永远不会release,使得线程死锁。

RLock对象允许一个线程多次对其进行acquire操作,因为在其内部通过一个counter变量维护着线程acquire的次数。而且第一次的acquire操作必须有一个release操作与之对应,在所有的release操作完成之后,别的线程才能申请该RLock对象。

例子:

import threading

mylock = threading.RLock()
num = 0


class myThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self, name=name)

    def run(self):
        global num
        while True:
            mylock.acquire()
            print('%s locked,Number:%d' % (threading.current_thread().name, num))
            if num >= 4:
                print('%s release,Number:%d' % (threading.current_thread().name, num))
                break

            num += 1
            print('%s release,Number:%d' % (threading.current_thread().name, num))
            mylock.release()


if __name__ == '__main__':
    thread1 = myThread('Thread_1')
    thread2 = myThread('Thread_2')
    thread1.start()
    thread2.start()
结果:

Thread_1 locked,Number:0
Thread_1 release,Number:1
Thread_1 locked,Number:1
Thread_1 release,Number:2
Thread_1 locked,Number:2
Thread_1 release,Number:3
Thread_1 locked,Number:3
Thread_1 release,Number:4
Thread_1 locked,Number:4
Thread_1 release,Number:4

 

全局解释器锁(GIL)

在Python的原始解释器CPython中存在着GIL(Global Interpreter Lock,全局解释器锁),因此在解释执行Python代码时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL。由于全局解释器锁的存在,在进行多线程操作的时候,不能调用多个CPU内核,只能利用一个内核,所以在进行CPU密集型操作的时候,不推荐使用多线程,更加倾向于多进程。

那么多线程适合什么样的应用场景呢?

对于IO密集型操作,多线程可以明显提高效率,例如Python爬虫的开发,绝大多数时间爬虫是在等待socket返回数据,网络IO的操作延时比CPU大得多。

 

进程和线程的区别和联系 我们都知道计算机的核心是CPU,它承担了所有的计算任务,而操作系统是计算机的管理者,它负责任务的调度,资源的分配和管理,统领整个计算机硬件;应用程序是具有某种功能的程序,程序是运行于操作系统之上的。 进程 进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程... 阅读详情

相关推荐

ros2 humble中使用realsense t265与d435

前提,安装realsense SDK 2.51.1版本并且能成功启动realsense-viewer V2.51.1想要在ros2中使用realsense t265,必须配合realsense SDK v2.51.1使用realsense-ros 4.51.1版本,因为新版本realsense ros2不再对t265支持下面记录源码编译安装 realsense-ros 4.51.1版本。

m0_72797388的博客 952

Python爬虫进阶:进程

进程介绍 python开发中,进程与线程是非常重要的,打造分布式爬虫,提高工作效率都离不开进程与线程。 进程 进程就是一个程序在一个数据集上的一次动态执行过程。 进程一般由程序、数据集、进程控制块三部分组成。我们编写的程序用来描述进程要完成哪些功能以及如何完成;数据集则是程序在执行过程中所需要使用的资源;进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,...

xiaoyaGrace的博客 197

STM32F0实现数字化SPWM纯正弦波逆变器

这个没啥好说的,搭电路的事。其核心思想是两边桥臂分别由两个180度相位差的正弦波与三角载波比较来控制,优点是在开关器件工作频率一样的情况下,输出PWM频率是单极性SPWM的2倍,能够明显减少谐波,因此只需要相对较小的电感和电容滤波器件就可以起到很好的滤波效果,提升了系统的性能,也精简了系统体积,降低了成本。而双极性pwm则是在整个正弦周期内,四只管子都在高频开关状态工作,对角线上的管子一起导通,另一对角线上管子互补导通,实际上只需要一路互补的PWM控制,负载上电压在正电压和负电压之间切换,不出现0v。

forlifefor的专栏 1万+

进程和线程的区别

转自文章进程和线程的区别 1、根本区别 进程和线程的根本区别是进程是操作系统资源(OS)分配的基本单位,而线程是处理器(CPU)任务调度和执行的基本单位。 2、资源开销: 每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。 3、包含关系: 如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线 同完成的;线程是进程的一部分,所行过程不愿一条绿的,而

qq_40855100的博客 2万+

通达信K线主图指标公式实战:如何用颜色标记快速识别涨停与炸板信号

本文详细介绍了如何利用通达信K线主图指标公式,通过颜色标记快速识别涨停与炸板等关键信号。通过实战拆解公式源码,手把手教您构建直观的“视觉交易系统”,将复杂的K线形态转化为醒目的颜色信号,帮助投资者高效聚焦机会与风险,提升技术分析效率。

weixin_29302047的博客 1749

不只是CPU主频:深入解析英飞凌Aurix TC3xx各外设时钟树(CAN、以太网、Flash时序如何配置)

本文深入解析英飞凌Aurix TC3xx系列微控制器的外设时钟树配置,涵盖CAN、以太网和Flash时序的优化方法。通过详细分析时钟系统架构、关键外设配置及多外设协同设计策略,帮助工程师实现高性能汽车电子控制单元(ECU)开发。特别关注系统时钟的灵活配置与EMC优化技巧,提升系统实时性和可靠性。

weixin_29189373的博客 400

线程和进程 / 进程和线程的区别和联系

💻进程(process) 🎃进程的特点 📢进程跟程序不一样 🎯进程状态 📠线程(Thread) 🔦线程的特点 🚢进程 VS 线程 🛫区别 💡Tips:堆和方法区 🧧多进程和多线程区别

qq_60021974的博客 7710

2026.3.10:最新claude code完美解决方案,跳过登录界面,使用国内deepseek-v4-pro进行计费

本文介绍了一种绕过Claude登录界面直接使用国内DeepSeek-V4-Pro服务的解决方案。通过npm全局安装@anthropic-ai/claude-code包,并配置5个关键环境变量:API认证令牌、基础URL(指向DeepSeek服务)、指定模型为deepseek-v4-pro、禁用非必要流量等。文中提供了4张配图辅助说明配置过程,但未展示具体内容。该方案可实现直接计费使用,无需通过官方登录流程。

拥抱具身智能,昇腾Ascend C 6502

Linux进程和线程的区别和联系

Linux中,线程是CPU调度和分派的基本单位,进程是分配资源的基本单位(操作系统)

qq_44846784的博客 2489

TC3XX - MCAL知识点(九):PWM EB-tresos配置说明及代码浅析

脉冲宽度调制(PWM)驱动器负责提供与AUTOSAR指定的PWM信号生成相关的标准服务。PWM通道的底层定时器驱动是GTM (TOM或ATOM片)或CCU6 (T12或T13片)定时器通道。软硬件匹配关系如下:PWM直接引用的是GTM与CCU6模块,然后GTM与CCU6再关联到Port的,根据软硬件匹配关系,也能调用中断来使用,本例子没使用中断。CCU6是一个高分辨率的16位捕获和比较单元,具有特定的应用模式,主要用于交流驱动控制。特殊的工作模式支持控制无刷直流电机使用霍尔传感器或反电动势检测。

梦想技术家 2885

PCB制造工艺参数到AD规则设置

本文提供了PCB设计与制造的落地指南,强调需先了解PCB厂的工艺参数,再在Altium Designer中设置相应规则。核心步骤包括:获取PCB厂的关键工艺参数(线宽/线距、过孔尺寸等),在AD中设置电气规则、布线规则、阻焊规则等,并进行DRC检查。文章还给出了常见问题避坑建议和快速落地模板,帮助设计师确保设计符合生产要求,避免因工艺不匹配导致的报废或成本增加。

qq_37999850的博客 292

线程和进程的区别

1. 进程(Process)进程是计算机中运行的一个程序的实例。它是操作系统分配资源和调度的基本单位,每个进程都有自己的内存空间、文件描述符和其他资源。每个进程都有独立的地址空间。进程之间的通信需要通过进程间通信(IPC)机制,例如管道、信号量或消息队列。进程是重量级的,创建和销毁成本较高。2. 线程(Thread)线程是进程中的一个执行单元,是CPU调度的基本单位。一个进程可以包含多个线程,它们共享进程的资源。线程之间共享同一个进程的内存空间和资源(例如堆和全局变量)。

Flying_Fish_roe的博客 5979

吊打原版YOLOv8!ASF-YOLO多尺度融合+注意力机制实战解析(遥感/医疗/质检均适用)

ASF-YOLO融合YOLOv8的创新目标检测框架摘要 ASF-YOLO是针对小目标检测优化的先进框架,采用三重特征编码器和尺度序列融合技术增强多尺度特征提取能力。核心创新包括: 三重特征编码器(TPE)融合跨层级信息 尺度序列特征融合(SSFF)模块通过3D卷积处理多尺度信息 通道-位置注意力机制(CPAM)聚焦关键特征区域 Zoom_cat模块实现自适应多尺度特征融合 该框架特别适用于医学影像、遥感检测等小目标密集场景,通过动态特征权重调整显著提升检测精度。关键技术实现包含多尺度特征统一、3D卷积序列处

FJN110的博客 527

线程和进程

这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。当有某个任务完成的时候,会yield这个任务,就能执行for循环下面的语句,然后继续阻塞住,循环到所有任务结束,同时,先完成的任务会先返回给主线程。

qq_45726327的博客 1211

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java之进程和线程

深入理解进程和线程 生动形象的比喻: 进程:一个车间 = 一个进程; (即一个运行的程序) 多进程:一座工厂可以同时运行多个车间; CPU和进程:单CPU只能同时运行单个进程,多CPU可以同时运行多个进程。 线程分为单线程和多线程 单线程:车间内一个工人 = 一个线程; 多线程:车间内多个工人 = 多个线程; 进程与线程:一个进程可以包括多个线程。 线程间内存共享:一个车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。 同理一个进程的内存空间是共享的,里面的每个线..

NoviceZ的博客 996

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

进程和线程区别、进程和进程,线程和线程怎么通信

1 进程和线程区别 根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位 在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。 所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线...

每天多学一点点. 的博客 545

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

程序、进程和线程

本文主要介绍程序、进程和线程的基本概念和进程的一些相关知识。提示:以下是本篇文章正文内容,下面案例可供参考程序(Program)是由程序员编写的一组稳定的指令,保存咋爱硬盘上。进程(Process)是运行中的程序,存在于内存(包括虚拟内存)中。线程(Thread)是利用CPU的一个基本单位,也称轻量级进程。程序是一个静态的被动实体,程序员编写(编译、链接生成可执行代码)完以后就保存在硬盘上,进程是一个动态的主动实体,运行某个程序(操作系统需要把程序调入内存)的时候才会产生进程,进程是与运行密切相关的。

zk124_的博客 1315
上一篇: socket模块
下一篇: 封装爬虫数据
linuxvfast
博客等级 码龄10年 6粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值