欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

py 并发编程(线程、进程、协程)

程序员文章站 2023-01-22 21:08:51
一、操作系统操作系统是一个用来协调、管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间。程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等。操作系统的内核的定义:操作系统的内核是一个管理和控制程序,负责管理计算机的所有物理资源,其中包括:文件系统、内存管理、设备管理和... ......

一、操作系统

操作系统是一个用来协调、管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间。
程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等。操作系统的内核的定义:操作系统的内核是一个管理和控制程序,负责管理计算机的所有物理资源,其中包括:文件系统、内存管理、设备管理和进程管理

二、进程和线程

进程:
    假如有两个程序a和b,程序a在执行到一半的过程中,需要读取大量的数据输入(i/o操作),
    而此时cpu只能静静地等待任务a读取完数据才能继续执行,这样就白白浪费了cpu资源。
    是不是在程序a读取数据的过程中,让程序b去执行,当程序a读取完数据之后,让程序b暂停,然后让程序a继续执行?
    当然没问题,但这里有一个关键词:切换
    既然是切换,那么这就涉及到了状态的保存,状态的恢复,加上程序a与程序b所需要的系统资
    源(内存,硬盘,键盘等等)是不一样的。自然而然的就需要有一个东西去记录程序a和程序b
    分别需要什么资源,怎样去识别程序a和程序b等等,所以就有了一个叫进程的抽象概念。

进程定义:
    进程就是一个程序在一个数据集上的一次动态执行过程。
    进程一般由程序、数据集、进程控制块三部分组成。

    数据集是程序在执行过程中所需要使用的资源;
    进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系
    统感知进程存在的唯一标志。

线程:
   线程的出现是为了降低上下文切换的消耗,提高系统的并发性,并突破一个进程只能干一样事的缺陷,
使到进程内并发成为可能。
   线程也叫轻量级进程,它是一个基本的cpu执行单元,也是程序执行过程中的最小单元,由线程id、程序
计数器、寄存器集合和堆栈共同组成。
   线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能。
   线程没有自己的系统资源。
线程进程的关系区别:
  1 一个程序至少有一个进程,一个进程至少有一个线程.(进程可以理解成线程的容器)
  2 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
  3 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和
  4   程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  5 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调
  6   度的一个独立单位.
  7   线程是进程的一个实体,是cpu调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程
  8   自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈)但是
  9   它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
 10   一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
但是python的gil(全局解释锁)会限制同一时刻被cpu调度的线程数量,也就是说无论你启多少个线程,你有多少个cpu, python在执行的时候在同一时刻只允许一个线程运行。为实现多cpu并行效果只能开多线程+协程。
对于io密集型的任务,python的多线程是有意义的,对于计算密集型的任务
python不适用。

线程与threading模块

threading 模块建立在thread 模块之上。thread模块以低级、原始的方式来处理和控制线程,而threading 模块通过对thread进行二次封装,提供了更方便的api来处理线程。

直接调用:
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("ending......")
threading.thread的实例方法
import threading
from time import ctime,sleep
import time

def listenmusic(name):

        print ("begin listening to %s. %s" %(name,ctime()))
        sleep(3)
        print("end listening %s"%ctime())

def recordblog(title):

        print ("begin recording the %s! %s" %(title,ctime()))
        sleep(5)
        print('end recording %s'%ctime())


threads = []


t1 = threading.thread(target=listenmusic,args=('水手',))
t2 = threading.thread(target=recordblog,args=('python线程',))

threads.append(t1)
threads.append(t2)

if __name__ == '__main__':

    for t in threads:
        #t.setdaemon(true) #注意:一定在start之前设置
        t.start()
        # t.join()在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
    # t1.join()
    t1.setdaemon(true)

    #t2.join()########考虑这三种join位置下的结果?
    print ("all over %s" %ctime())