Python 基础之-进程线程

Posted cyfiy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 基础之-进程线程相关的知识,希望对你有一定的参考价值。

进程与线程

 

什么是进程

程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。

在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。

 

有了进程为什么还要线程?

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

  • 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。

  • 进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。

例如,我们在使用qq聊天, qq做为一个独立进程如果同一时间只能干一件事,那他如何实现在同一时刻 即能监听键盘输入、又能监听其它人给你发的消息、同时还能把别人发的消息显示在屏幕上呢?你会说,操作系统不是有分时么?但我的亲,分时是指在不同进程间的分时呀, 即操作系统处理一会你的qq任务,又切换到word文档任务上了,每个cpu时间片分给你的qq程序时,你的qq还是只能同时干一件事呀。

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

 

什么是线程

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

 

进程和线程的区别

(1)进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
          (2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程。
          (3)进程的创建调用fork或者vfork,而线程的创建调用pthread_create,进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
          (4)线程是轻量级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
          (5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
          (6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志
 
 
Python threading模块
 
线程有2种调用方式,如下:
直接调用
import threading
import time


def sayhi(num):  # 定义每个线程要运行的函数

    print("running on number:%s" % num)

    time.sleep(3)


if __name__ == __main__:
    t1 = threading.Thread(target=sayhi, args=(1,))  # 生成一个线程实例
    t2 = threading.Thread(target=sayhi, args=(2,))  # 生成另一个线程实例

    t1.start()  # 启动线程
    t2.start()  # 启动另一个线程

    print(t1.getName())  # 获取线程名
    print(t2.getName())

 

继承式调用

import threading
import time


class MyThread(threading.Thread):
    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self):  # 定义每个线程要运行的函数

        print("running on number:%s" % self.num)

        time.sleep(3)


if __name__ == __main__:
    t1 = MyThread(1)
    t2 = MyThread(2)
    t1.start()
    t2.start()
    print(t1.getName())  # 获取线程名
    print(t2.getName())

 

下面是一个对多线程的一个处理方法:(需要理解):

import threading
import time

def run(n):
    print("task: ",n)
    time.sleep(2)
    print("task done: ",n)

start_time = time.time()
for i in range(10):
    t = threading.Thread(target=run,args=(i,))
    t.start()

print("cost: ",time.time() - start_time)

运行结果如下所示:

 

 是因为这个程序本身就是一个主线程,主线程又起了子线程,这时子线程和主线程已经没关系了,相当于子线程和主线程是并行的。这就解释了为什么我的主线程启动了子线程之后,没有等子线程执行完毕,主线程就继续往下走了。

 

但是现在有个问题,我们需要计算所有线程的执行时间,并且让所有线程运行之后再运行主程序

这里就需要用到线程里的一个方法join()意思其实就是等待的意思代码如下:

import threading
import time

def run(n):
    print("task: ",n)
    time.sleep(2)
    print("task done: ",n)

start_time = time.time()
t_obj = []    #存线程实例
for i in range(10):
    t = threading.Thread(target=run,args=(i,))
    t.start()
    t_obj.append(t)    #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里

for i in t_obj:    #循环线程实例列表,等待所有线程执行完毕
    i.join()

print("all thread is done")
print("cost: ",time.time() - start_time)

 

没有加join的时候,主线程不会等子线程执行完毕再往下走,主线程和子线程的执行完全是并行的,没有依赖关系,你执行,我也执行。但是,你会发现,最终退出的时候,主线程依然会等待所有的子线程执行完毕才退出程序。虽然不等你执行完毕才往下走,但是在程序退出之前,会默认还有一个join

但加了join的时候,主线程依赖子线程执行完毕之后, 再往下走,这是JOIN 的作用。

 

关于守护线程

如果将线程设置为守护线程,则主程序不会管线程是否执行完,只有主程序执行完毕之后,就会结束

代码例子如下:

import threading
import time

def run(n):
    print("task: ",n)
    time.sleep(2)
    print("task done: ",n)

start_time = time.time()

for i in range(10):
    t = threading.Thread(target=run,args=(i,))
    t.setDaemon(True)    #把当前线程设置为守护线程
    t.start()

print("all thread is done",threading.current_thread(),threading.active_count())
print("cost: ",time.time() - start_time)

 

 

 
 

以上是关于Python 基础之-进程线程的主要内容,如果未能解决你的问题,请参考以下文章

python并发编程之多线程基础知识点

Python 基础之 线程与进程

Python 基础之-进程线程

python基础之进程线程

Python最详细的零基础入门之——多线程详解!

python基础之进程间通信进程池协程