进程和线程的区别

本文详细阐述了线程与进程的概念、它们之间的区别以及如何在Python中实现多线程和多进程。此外还介绍了线程间同步机制——互斥锁,并讨论了死锁问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关系:线程是进程的基本执行单元,一个进程的所有任务都在线程中执行;进程要想执行任务,必须得有线程。

区别:1、同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间;2、同一进程内的线程共享本进程的资源,而进程间的资源是独立的。

线程和进程的关系

线程定义

线程是进程的基本执行单元,一个进程的所有任务都在线程中执行

进程要想执行任务,必须得有线程,进程至少要有一条线程

程序启动会默认开启一条线程,这条线程被称为主线程或 UI 线程

进程定义

进程是指在系统中正在运行的一个应用程序

每个进程之间是独立的,每个进程均运行在其专用的且受保护的内存

进程与线程的区别

地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

资源拥有:同一进程内的线程共享本进程的资源(如内存、I/O、cpu等),但是进程之间的资源是独立的。

一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程

执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

线程是处理器调度的基本单位,但是进程不是。

扩展资料:多线程的意义

优点

  1. 能适当提高程序的执行效率
  2. 能适当提高资源的利用率(CPU,内存)
  3. 线程上的任务执行完成后,线程会自动销毁

缺点

  1. 开启线程需要占用一定的内存空间(默认情况下,每一个线程都占 512 KB)
  2. 如果开启大量的线程,会占用大量的内存空间,降低程序的性能
  3. 线程越多,CPU 在调用线程上的开销就越大
  4. 程序设计更加复杂,比如线程间的通信、多线程的数据共享

python代码实现

线程

方案一

'''
线程,进程
进程是资源单元,每一个进程至少要有一个线程
线程是执行单位
启动每一个程序默认都会有一个主线程
'''
from threading import Thread # 线程类

def func(name):
    for i in range(1000):
        print(name, i)

if __name__ == "__main__":
    t1 = Thread(target=func, args=("周杰伦",)) # 创建线程并给线程安排任务
    t1.start() # 多线程状态为可以开始工作状态,具体的执行时间由CPU决定
    
    t2 = Thread(target=func, args=("王力宏",))
    t2.start()

方案二

class MyThread(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):  # 固定的 -> 当线程被执行的时候,被执行的就是run()
        for i in range(1000):
            print(self.name, i)

if __name__ == "__main__":
    t1 = MyThread('周润发')
    t1.start()

    t2 = MyThread('李连杰')
    t2.start()

进程

from multiprocessing import Process

def func(name):
    for i in range(1000):
        print(name, i)
    
if __name__ == "__main__":
    p1 = Process(target=func, args=("周杰伦",))
    p1.start()
    p2 = Process(target=func, args=("王力宏",))
    p2.start()

互斥锁

如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。最简单的同步机制就是引入互斥锁。

锁有两种状态——锁定和未锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”状态,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

使用 Thread 对象的 Lock 可以实现简单的线程同步,有上锁 acquire 方法和 释放release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。

import time
from threading import Thread,Lock
#定义全局变量num
num=0
#创建一把互斥锁
mutex=Lock()
def test1():
    global num
    '''
    在两个线程中都调用上锁的方法,则这两个线程就会抢着上锁,
    如果有1方成功上锁,那么导致另外一方会堵塞(一直等待)直到这个锁被解开
    '''
    mutex.acquire()#上锁
    for i in range(100000):
        num+=1
    mutex.release()
    print('test1输出num:',num)

def test2():
    global num
    mutex.acquire()  # 上锁
    for i in range(100000):
        num+=1
    mutex.release()
    print('test2输出num:',num)

if __name__=='__main__':
    t1=Thread(target=test1)
    t2=Thread(target=test2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

执行结果如图所示:
在这里插入图片描述
【示例】互斥锁改进

import time
from threading import Thread,Lock
#定义全局变量num
num=0
#创建一把互斥锁
mutex=Lock()
def test1():
    global num
    '''
    在两个线程中都调用上锁的方法,则这两个线程就会抢着上锁,
    如果有1方成功上锁,那么导致另外一方会堵塞(一直等待)直到这个锁被解开
    '''
    for i in range(100000):
        mutex.acquire()  # 上锁
        num+=1
        mutex.release()
    print('test1输出num:',num)

def test2():
    global num
    for i in range(100000):
        mutex.acquire()  # 上锁
        num+=1
        mutex.release()
    print('test2输出num:',num)

if __name__=='__main__':
    t1=Thread(target=test1)
    t2=Thread(target=test2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

执行结果如图所示:
在这里插入图片描述

死锁

在线程共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。

import time
from threading import Thread,Lock
import threading
mutexA=threading.Lock()
mutexB=threading.Lock()
class MyThread1(Thread):
    def run(self):
        if mutexA.acquire():
            print(self.name,'执行')
            time.sleep(1)
            if mutexB.acquire():
                print(self.name,'执行')
                mutexB.release()
            mutexA.release()


class MyThread2(Thread):
    def run(self):
        if mutexB.acquire():
            print(self.name,'执行')
            time.sleep(1)
            if mutexA.acquire():
                print(self.name,'执行')
                mutexA.release()
            mutexB.release()

if __name__ == '__main__':
    t1=MyThread1()
    t2=MyThread2()
    t1.start()
    t2.start()

在这里插入图片描述

进程线程是操作系统中的两个重要概念,它们有以下区别: 1. 进程是指在操作系统中正在运行的一个程序,它是系统分配资源的基本单位;而线程是指进程内部的一个执行单元,它是CPU调度的基本单位。 2. 进程之间相互独立,一个进程崩溃不会影响其他进程的运行;而进程内部的线程共享进程的资源,包括内存、文件、网络连接等,一个线程的崩溃可能会导致整个进程的崩溃。 3. 创建进程的开销比创建线程的开销大,因为进程需要独立的地址空间系统资源;线程的开销相对较小,因为它们共享进程的资源。 4. 进程之间通信比较麻烦,需要使用进程间通信机制;而线程之间通信比较简单,可以通过共享内存等方式实现。 下面给出一个python的例子来说明进程线程区别: 1.创建进程[^1] ```python import os def run_proc(name): print('Child process %s (%s) Running...' % (name, os.getpid())) if __name__ == '__main__': print('Parent process %s.' % os.getpid()) p = Process(target=run_proc, args=('test',)) print('Child process will start.') p.start() p.join() print('Child process end.') ``` 2.创建线程[^2] ```python import threading def run_thread(name): print('Thread %s is running...' % name) if __name__ == '__main__': print('Parent thread %s.' % threading.currentThread().getName()) t1 = threading.Thread(target=run_thread, args=('test',)) t2 = threading.Thread(target=run_thread, args=('test2',)) print('Thread %s will start.' % t1.getName()) print('Thread %s will start.' % t2.getName()) t1.start() t2.start() t1.join() t2.join() print('Thread %s end.' % threading.currentThread().getName()) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting_1997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值