进程和线程(Python)

进程和线程(Python)

1、什么是进程?

  • 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
  • 在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。

2、什么是线程?

  • 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务

3、为什么有了进程还需要线程?

  • 进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:

    • 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
    • 进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。
  • 例如,我们在使用qq聊天, qq做为一个独立进程如果同一时间只能干一件事,那他如何实现在同一时刻 即能监听键盘输入、又能监听其它人给你发的消息、同时还能把别人发的消息显示在屏幕上呢?

    直白一点, 一个操作系统就像是一个工厂,工厂里面有很多个生产车间,不同的车间生产不同的产品,每个车间就相当于一个进程,且你的工厂又穷,供电不足,同一时间只能给一个车间供电,为了能让所有车间都能同时生产,你的工厂的电工只能给不同的车间分时供电,但是轮到你的qq车间时,发现只有一个干活的工人,结果生产效率极低,为了解决这个问题,应该怎么办呢?。。。。没错,你肯定想到了,就是多加几个工人,让几个人工人并行工作,这每个工人,就是线程!

4、进程和线程的区别:

  • 进程是资源分配的最小单元,线程是CPU调度的最小单元
  • 线程共享创建它的进程的地址空间;进程有自己的地址空间
  • 线程可以直接访问其进程的数据段;进程有自己的父进程数据段副本
  • 线程可以直接与其进程的其他线程通信;进程必须使用进程间通信来与同级进程通信
  • 进程中第一个线程是主线程,主线程能够建立其余线程;其余线程也能够建立线程;线程之间是平等的
  • 进程有父进程和子进程,独立的内存空间,惟一的标识符:pid

5、python是如何启动线程的?

  • Python当中为我们提供了完善的threading库,通过它,我们可以非常方便地创建线程来执行多线程。首先,我们引入threading中的Thread,这是一个线程的类,我们可以通过创建一个线程的实例来执行多线程。
from threading import Thread

t = Thread(target=func, name='therad', args=(x, y))

t.start()
  • 简单解释一下它的用法,我们传入了三个参数,分别是target,name和args
    • 从名字上我们就可以猜测出它们的含义。首先是target,它传入的是一个方法,也就是我们希望多线程执行的方法。name是我们为这个新创建的线程起的名字,这个参数可以省略,如果省略的话,系统会为它起一个系统名。当我们执行Python的时候启动的线程名叫MainThread,通过线程的名字我们可以做区分。args是会传递给target这个函数的参数。

举个经典的例子:

import time, threading
# 新线程执行的代码:

def loop(n):

    print('thread %s is running...' % threading.current_thread().name)

    for i in range(n):

        print('thread %s >>> %s' % (threading.current_thread().name, i))

        time.sleep(5)

    print('thread %s ended.' % threading.current_thread().name)

print('thread %s is running...' % threading.current_thread().name)

t = threading.Thread(target=loop, name='LoopThread', args=(10, ))

t.start()

print('thread %s ended.' % threading.current_thread().name)

  • 我们创建了一个非常简单的loop函数,用来执行一个循环来打印数字,我们每次打印一个数字之后这个线程会睡眠5秒钟,所以我们看到的结果应该是每过5秒钟屏幕上多出一行数字。
thread MainThread is running...     # 主进程
thread LoopThread is running...thread MainThread ended.

thread LoopThread >>> 0
thread LoopThread >>> 1
thread LoopThread >>> 2
thread LoopThread >>> 3
thread LoopThread >>> 4
thread LoopThread >>> 5
thread LoopThread >>> 6
thread LoopThread >>> 7
thread LoopThread >>> 8
thread LoopThread >>> 9
thread LoopThread ended.

ps:顺序问题需要自己运行看,0和主进程几乎是一块结束的

  • 输出的顺序不太对

    • 为什么我们在打印了第一个数字0之后,主线程就结束了呢?另外一个问题是,既然主线程已经结束了,
  • 为什么Python进程没有结束, 还在向外打印结果呢?

    • 因为线程之间是独立的,对于主线程而言,它在执行了t.start()之后,并不会停留,而是会一直往下执行一直到结束。如果我们不希望主线程在这个时候结束,而是阻塞等待子线程运行结束之后再继续运行,我们可以在代码当中加上t.join()这一行来实现这点。
t.start()
t.join()

print('thread %s ended.' % threading.current_thread().name)

join操作可以让主线程在join处挂起等待,直到子线程执行结束之后,再继续往下执行。我们加上了join之后的运行结果是这样的:

thread MainThread is running...
thread LoopThread is running...
thread LoopThread >>> 0
thread LoopThread >>> 1
thread LoopThread >>> 2
thread LoopThread >>> 3
thread LoopThread >>> 4
thread LoopThread >>> 5
thread LoopThread >>> 6
thread LoopThread >>> 7
thread LoopThread >>> 8
thread LoopThread >>> 9
thread LoopThread ended.
thread MainThread ended.

我们再来看第二个问题,为什么主线程结束的时候,子线程还在继续运行,Python进程没有退出呢?这是因为默认情况下我们创建的都是用户级线程,对于进程而言会等待所有用户级线程执行结束之后才退出

这里就有了一个问题,那假如我们创建了一个线程尝试从一个接口当中获取数据,由于接口一直没有返回,当前进程岂不是会永远等待下去?这显然是不合理的,所以为了解决这个问题,我们可以把创建出来的线程设置成守护线程

6、什么是守护线程?

守护线程即daemon线程,它的英文直译其实是后台驻留程序,所以我们也可以理解成后台线程,这样更方便理解。daemon线程和用户线程级别不同,进程不会主动等待daemon线程的执行,当所有用户级线程执行结束之后即会退出。进程退出时会kill掉所有守护线程。我们传入daemon=True参数来将创建出来的线程设置成后台线程:

t = threading.Thread(target=loop, name='LoopThread', args=(10, ), daemon=True)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值