19进程线程概述

并发编程

  1. 为什么要有操作系统
    操作系统就是用户界面和底层硬件的桥梁
    向下管理硬件,向上提供接口

  2. 操作系统“切换”实现单核并发

    • 出现io操作
    • 固定时间

进程定义:

资源管理单位(容器)
进程就是一个程序在一个数据集上的一次动态执行过程。进程一般有程序、数据集、进程控制块三部分组成。
程序用来描述进程要完成哪些功能以及如何完成;数据集则程序在执行过程中所需要使用的资源;进程那个控制块用来进程的外部特征,描述进程的执行变化过程,系统可以利用他来控制和管理进程,他是系统感知进程存在的唯一标识。

当多个进程需要用到同一块数据集的时候,或者进程之间需要进行数据交互的时候,就出现了数据集复用占用内存等问题。

线程:

微进程

最小执行单位
线程的出现就是为了降低上下文切换的消耗

python的线程锁

python程序运行的时候,由于GIL这把锁,一个进程中的线程只能同时只给单个CPU运行(只能实现时间复用),在多核的情况下,单个进程中的多线程也只能一个一个给单个CPU调用。

Treading

方式1:

import threading
import time
def tingge():
    print('listen song')
    time.sleep(3)
    print('listen over')

def xieboke():
    print('write blog')
    time.sleep(5)
    print('write over')
s = time.time()
t1 = threading.Thread(target = tingge)         #创建线程
t2 = threading.Thread(target = xieboke)        #创建线程

t1.start()        #子线程1
t2.start()        #子线程2

t1.join()        #挂起等待
t2.join()        #挂起等待

#.join()就是指进程结束后挂起等待,直到所有程序结束再运行下面的程序


print('ending')        #主线程
#三个线程是竞争关系,在速度足够快的情况下,三个线程看谁先抢到资源就谁先运行

print(time.time()-s)

方式2:
继承父类方法,并且重写run()函数

import threading, time


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

    def run(self):
        print('ok this is num %s' % self.num)
        time.sleep(self.sleep)
        print('over',self.sleep)

s = time.time()
t1 = MyThread(100,5)
t2 = MyThread(150,2)

t1.start()  # 默认调用run()方法
t2.start()

t1.join()        #挂起等待
t2.join()        #挂起等待

print('ending',time.time()-s)

join方法

被join的线程就必须运行完毕,其他程序的运行不管,如果被join的线程不结束,就阻塞主线程。

setDaemon方法

setDaemon(True)
将线程声明为守护线程,主线程结束的时候不会等守护线程,直接结束程序

import threading, time

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

    def run(self):
        print('ok this is num %s' % self.num)
        time.sleep(self.sleep)
        print('over',self.sleep)

s = time.time()
t1 = MyThread(100,5)
# t2.setDaemon(True)
t2 = MyThread(150,2)
t1.setDaemon(True) #设置t1为守护线程,也就是说在主线程结束的时候,t1会直接结束,而t2不受守护线程约束,可以完整跑完
t1.start()  # 默认调用run()方法
t2.start()

print('ending',time.time()-s)

结果:

ok this is num 100
ok this is num 150
ending 0.0
over 2

GIL全局解释器锁

加在cpython解释器上

缺点:多处理器退化为单处理器
优点:避免大量的枷锁解锁操作

总结:
对于计算密集型的任务,python的多线程并没有用
对于IO密集型的任务,python的多线程是有意义的。

python使用多核:开进程,弊端就是开销非常大,而且切换(进程间通讯)复杂。

解决问题的着重点:协程+多进程/IO多路复用/换C模块实现多进程

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

原文地址:https://www.cnblogs.com/scott-lv/p/7487293.html