首页 > 编程语言 >Python_异步编程-并发编程-协程和future

Python_异步编程-并发编程-协程和future

时间:2024-11-26 11:43:48浏览次数:6  
标签:文件 调用 协程 Python 编程 接口 线程 进程

操作系统创建线程

 Unix进程的设计思想,实现了 fork exec wait exit 四个精巧的系统调用来支持对进程的灵活管理。
      父进程进程通过 fork 系统调用创建自身的副本(子进程);
      称为“子进程”的副本可调用 exec 系统调用用另一个程序覆盖其内存空间,这样就可以执行新程序了;
      子进程执行完毕后,可通过调用 exit 系统调用来退出并通知父进程;
      父进程通过调用 wait 系统调用来等待子进程的退出
 
 我们为什么不设计一个系统调用接口同时实现创建一个新进程并加载给定的可执行文件两种功能
     拆分为两个系统调用后,可以灵活地支持 重定向 (Redirection) 等功能		  
 
 但DOS/WINDOWS还有spawn类函数,
      因为DOS是单任务的系统,它只能将"父进程"驻留在机器内再执行"子进程",这就是spawn类的函数
 	 Windows 中, CreateProcess 函数用来创建一个新的进程和它的主线程,通过这个新进程运行指定的可执行文件
 posix-spawn
 	  POSIX 标准的 posix_spawn 系统调用则类似 Windows 的 CreateProcess 函数,不过对参数进行了简化
 	    posix-spawn是基于POSIX标准的进程创建方法,可以方便地替代传统的fork()和exec()调用

开发语言创建线程-并发

仓颉语言中通过关键字 spawn 创建仓颉线程-即用户态协程		
	
fork:除了必要的启动资源外,其他变量,包,数据等都继承自父进程,并且是copy-on-write的,也就是共享了父进程的一些内存页,因此启动较快,
但是由于大部分都用的父进程数据,所以是不安全的进程

spawn:从头构建一个子进程,父进程的数据等拷贝到子进程空间内,拥有自己的Python解释器,
所以需要重新加载一遍父进程的包,因此启动较慢,由于数据都是自己的,安全性较高

POSIX标准中的 posix_spawn 或者
Linux 上的 clone 系统调用

###进程方式     
      	线程的并行: 独立的地址空间 独立的资源 相互隔离
		线程的并发:进程的并发性指的是多个进程在同一时间段内交替执行的能力

进程

1.进程本身-组成:进程内部由哪些部分构成  Info
  进程是动态--需要相应硬件资源支持--时间和空间的生命周期- 进程状态转换功能。
  即硬件/虚拟资源 进行 动态绑定和解绑 
    进程ID  进程描述数据块PCB  进程实体(程序段-数据段和进程控制块Process Control Block)
    生命周期状态::包括 创建进程、就绪状态、运行状态、阻塞进程、终止进程等 进程资源回收机制

2.进程相互制约--通信_多个进程之间的组织方式问题
      同步
	  互斥
	  临界资源和临界区  信号量和P/V值   共享资源
	   竞态条件 死锁:
    进程通信-进程之间的信息交换		  
      1.共享存储-通过对这片共享空间进行写/读操作实现进程之间的信息交换
      2.消息传递:进程通过系统提供的发送消息和接收消息两个原语进行数据交换	
      3.管道通信:管道通信是消息传递的一种特殊方式  (互斥、同步和确定对方的存在)   I/O重定向 与 管道(pipe)
	  4.信号(Signals) 忽略  捕获  终止
  方式: 顺序方式 链接方式 索引方式
     链接方式和索引方式: 执行指针 就绪队列指针 阻塞队列指针 
  进程控制: 创建新进程、撤销已有进程、实现进程状态转换等功能 执行具有原子性
      用“关中断指令”和“开中断指令”这两个特权指令实现原子性	  
3.进程调度-调度(scheduling)
     指标: 周转时间(turn around),即进程完成时间(completion)与进程到达时间(arrival)的差值
      调度机制 
         最短完成时间优先 STCF—_Shortest Time to Complet First
	     先来先服务FIFO   
		 可抢占特性
		 基于时间片的轮转
		 最早截止时间优先(Earliest Deadline First,EDF)算法
	 操作系统通过硬件中断机制,支持分时多任务和抢占式调度机制
4.实现:
   设计一些数据结构包含的内容及接口
        基于应用名的应用链接、加载器、进程标识符 PidHandle、任务控制块 TaskControlBlock、任务管理器 TaskManager、处理器管理结构 Processor
	线程的数据不一致问题和竞态条件问题的根本原因是 调度的不可控性

操作系统抽象: 地址空间 、 进程 以及  文件 

文件 -文件描述符

  内核提供的 sys_open 系统调用让该文件在进程的文件描述符表中占一项,并得到操作系统的返回值–文件描述符
     管道: 新的系统调用 sys_pipe 和 sys_close  基于文件的管道
  进程能够通过一个统一的接口来读写内核管理的持久存储设备,这样数据可以方便地被长久保存。
      进程控制块中有一个 文件描述符表 ,在表中保存着多个 文件 记录信息。
	        每个文件描述符是一个非负的索引值,即对应文件记录信息的条目在文件描述符表中的索引
	基于文件的统一I/O抽象,将标准输入/标准输出的访问改造为基于文件描述符,然后同样基于文件描述符实现一种父子进程之间的通信机制——管
	将进程对于标准输入输出的访问修改为基于文件抽象的接口
文件操作
    打开(open)  :进程只有打开文件,操作系统才能返回一个可进行读写的文件描述符给进程,进程才能基于这个值来进行对应文件的读写;
        读(read):进程可以基于文件描述符来读文件内容到相应内存中;
        写(write):进程可以基于文件描述符来把相应内存内容写到文件中;
    关闭(close) :进程基于文件描述符关闭文件后,就不能再对文件进行读写操作了,这样可以在一定程度上保证对文件的合法访问;
内核中支持命令行参数的解析和传递

IO-设备操作标识

  让应用能便捷地访问外设	
      备驱动程序完成哪些功能:设备扫描/发现  设备初始化 通知设备 接收设备通知  卸载设备驱动时回收设备驱动资源
	  设备的硬件规范:
  操作系统重点关注的是如何对I/O设备进行管理,软件程序员则主要关注I/O设备为软件提供的接口(interface)
              件工程师看来,I/O设备就是一堆芯片、电源和其他电路的组

Python 多进程

 根据不同的平台, multiprocessing 支持三种启动进程的方法
     1.在 Windows 和 macOS 上:  spawn  父进程会启动一个新的 Python 解释器进程
	 2.在 POSIX 系统上可用   :  fork   POSIX 上为默认值父进程使用 os.fork() 来产生 Python 解释器分叉(除 macOS 之外的)
	                              fork 的代码应当显式地通过 get_context() 或 set_start_method() 来指定
	 3.支持通过 Unix 管道传递文件描述符的 POSIX 平台上可用,例如 Linux 
	                        当程序启动并选择 forkserver 启动方法时,将产生一个服务器进程
							
	multiprocessing.set_start_method('spawn')
	或者
	ctx = multiprocessing.get_context('spawn')
	
	
	
multiprocessing 支持进程之间的两种通信通道	:队列和管道:  Queue 类是一个近似 queue.Queue 的克隆	  Pipe() 函数返回一个由管道连接的连接对
        Pool 对象,它提供了一种快捷的方法,赋予函数并行化处理一系列输入值的能力,可以将输入数据分配给不同进程处理(数据并行)
		进程池: concurrent.futures.ProcessPoolExecutor
  生成进程:
      创建一个 Process 对象然后调用它的 start() 方法来生成进程
  进程通信:
       队列和管道
  进程间同步
      共享内存: 可以使用 Value 或 Array 将数据存储在共享内存映射中
  服务进程
     Manager() 返回的管理器对象控制一个服务进程,该进程保存Python对象并允许其他进程使用代理操作它们
    name   pid  is_alive()
    start()  run()
	join()
	terminate()  kill()  close()

Python 多线程

    _thread    --- 低层级多线程 API
	threading   ---高层级多线程 API
	
	
	sched 模块定义了一个实现通用事件调度程序的类
	    sched模块还支持处理一些常见的用例,如定时任务、周期性任务和时间限制的任务
		  实例化定时器--enter() 方法执行定时任务
		  延迟执行
		  固定时间执行
		  执行多个任务--不同优先级执行不同任务
		
popen 的返回值是个标准 I/O 流  pclose 来终止
    popen相当于是先创建一个管道,fork,关闭管道的一端,执行exec,返回一个标准的io文件指针。
    system相当于是先后调用了fork, exec,wait来执行外部命令
       popen本身是不阻塞的,要通过标准io的读取使它阻塞
       system本身就是阻塞的。

I/O模型

编程语言的io接口,其实是依赖底层的操作系统的实现
  IO从概念上来说,总共有5种:
 (1)阻塞IO (blocking I/O)
 (2)非阻塞IO (nonblocking I/O)
 (3)IO多路复用 (I/O multiplexing (select and poll))
 (4)事件驱动IO (signal driven I/O (SIGIO))
 (5)异步IO (asynchronous I/O (the POSIX aio_functions))
 
准备数据到内核的缓冲区0--从缓冲区拷贝到用户空间
   select,poll属于第三种-IO多路复用模型,
   iocp属于第5种异步io模型
    epoll,kqueue  epoll和kqueue是更先进的IO复用模型
	
	I/O多路复用模型就是通过一种机制,
	   一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

POSIX API

Windows API 

 进程管理接口:
     exit:进程终止
     fork:创建子进程
     wait:等待子进程结束
 	
 文件管理接口:
     open:打开文件
     close:关闭文件
     read:读取文件内容
     write:写入文件内容
 	
 目录管理接口:
     opendir:打开目录
     readdir:读取目录项
     closedir:关闭目录
 网络通信接口:
     socket:创建套接字
     bind:绑定套接字到地址
     listen:监听传入连接
     accept:接受传入连接
 线程和同步接口:
     pthread_create:创建线程
     pthread_join:等待线程结束
     pthread_mutex_lock:加锁互斥量
     pthread_cond_signal:发送条件变量信号
 信号处理接口:POSIX信号库
     signal:注册信号处理函数
     kill:向进程发送信号
     sigaction:设置信号处理动作
 时间和日期接口:
     time:获取当前时间
     clock:获取时钟时间
     strftime:格式化时间
 共享内存接口:
     shmget:获取共享内存标识符
     shmat:连接到共享内存
     shmdt:分离共享内存
 ioctl 接口:
     ioctl:控制设备操作
      用 fcntl() 和ioctl() 的接口。
 
      epoll 是Linux内核中实现的一种可扩展的I/O事件通知机制,
 	 unix为kqueue)
 	 FreeBSD中类似的实现是kqueue
 
   种IO复用模式之select,poll,epoll,kqueue,iocp分析

POSIX

 POSIX 是 可移植操作系统接口 Portable Operating System Interface 
    系统服务应用程序编程接口
	   POSIX主要分为四个部分:Base Definitions、System Interfaces、Shell and Utilities和Rationale

编程

  裸机编程、 Linux 驱动编程以及 Linux 应用编程	
  Linux应用编程:
      内核态和用户态,应用程序运行在用户态、而内核则运行在内核态。
	系统调用是内核提供给应用层的编程接口,属于系统内核的一部分
	库函数是属于应用层-运行在用户空间
	开发 Linux 应用程序,
	    通过调用内核提供的系统调用
		或使用 C 库函数来开发具有相应功能的应用程序
Linux系统调用接口非常精简(只有250个左右),
    Linux 3.2.0版本提供了380个系统调用,而FreeBSD 8.0提供的系统调用超过450个

并发编程

Producer-Consumer模式、Pipeline模式和Future模式
  Future模型是将异步请求和代理模式结合的产物
    future 本质上表达一个还没有准备好的值
 future、promise、delay 和 deferred 是指用于在某些并发编程语言中同步程序执行的构造。
    future和promise起源于函数式编程和相关范例,
	  目的是将值(future)与其计算方式(promise)分离
	 future最大的好处是将函数的同步调用转换为异步调用,适用于一个交易需要多个子调用且这些子调用没有依赖的场景
C++ 异步编程
   std::promise 是一个对象,可以保存某一类型 T 的值,该值在未来某个时间点可以被检索。
   std::future 代表一个异步操作的结果	
    C++20中引入了coroutine,从语言层面而不仅是实现方法层面实现异步操	   
	 
在Cangjie 仓颉编程语言 
    仓颉线程会返回一个Future<T>类型的结果
      Future 和 Thread 类型

在Rust中,Future作为一个接口在rust 1.36加入标准库中
      async:产生一个 Future 对象

在Java中 Future 模式是一种在并发编程中广泛使用的设计模式,用于表示一个可能还没有完成的异步操作的结果	
   在Java中,Future接口在java.util.concurrent包
   
在Go 
   编程中经常遇到在一个流程中需要调用多个子调用的情况,Go标准库并未直接提供Future或Promise这样的抽象概念
     这些子调用相互之间没有依赖,如果串行地调用,则耗时会很长,此时可以使用Go并发编程中的future模式	

Python 
    future对象,一般不会直接使用,它是task类的基类,task一部分的功能是future提供的,其是更低级的接口
	concurrent.futures 模块
	   Future对象是submit任务(即带有参数的functions)到executor的实例
		current.Futures提供了两种Executor的子类,各自独立操作一个线程池和一个进程池。这两个子类分别是:

   - concurrent.futures.ThreadPoolExecutor(max_workers)

   - concurrent.futures.ProcessPoolExecutor(max_workers)
在Scala中,可以使用Futures进行并行网络调用。
Future是一个表示异步计算结果的抽象,

 bind和callback,类似与boost库的bind和function	

并发设计模式

 Producer-Consumer模式(生产者-消费者) 非常经典的多线程并发协作的模型 解藕,异步,平衡速度差异
 Thread Pool模式(线程池): 这个模式就是为减少开启与关闭线程带来的开销
 Master-Slave模式(主仆)
 Pipeline模式(流水线)
 Promise模式帮我们不需要等待耗时的求值操作,而是拿一个凭证。我们可以先去做些别的,最后再回来取值
 mmutable Object模式(不可变对象): 过将对象变为只读的形式来保证线程安全,是比较好的无锁实现

参考

  https://man7.org/linux/man-pages/man2/syscalls.2.html	
  https://github.com/JnuSimba/LinuxSecNotes/tree/master	  ‌

标签:文件,调用,协程,Python,编程,接口,线程,进程
From: https://www.cnblogs.com/ytwang/p/18569838

相关文章

  • Python处理时间汇总-与时区相关的处理
    获取当前东八区时间以及统一时区的时间比较#coding:utf-8importpytzimportdatetime#定义东八区时区cst_timezone=pytz.timezone('Asia/Shanghai')#获取东八区的当前时间defget_cst_nowtime():returndatetime.datetime.now(cst_timezone)#将时间对象......
  • 实现异步编程有哪些方式?推荐用哪种?
    前端开发中实现异步编程的方式主要有以下几种:回调函数(Callbacks):这是最基础的异步编程方式。一个函数作为参数传递给另一个函数,并在异步操作完成后被调用。优点:简单易懂,容易上手。缺点:容易陷入“回调地狱”(嵌套过多的回调函数,导致代码难以阅读和维护)。错误处理也......
  • 嵌入式开发之UDP网络编程
    1、TCP编程的函数API1.1、网络发送数据:send()/write()#include<sys/types.h>#include<sys/socket.h>ssize_tsend(intsockfd,constvoid*buf,size_tlen,intflags);#include<unistd.h>ssize_twrite(intfd,constvoid*buf,size_tcount);send()比write多......
  • Shell脚本编程基础
    一、构建基本脚本1.1使用多个命令两个命令一起运行,放在同一行,用;隔开,例如pwd;ls1.2创建shell脚本在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。其格式为:#!/bin/bash井号(#)用作注释行。shell并不会处理shell脚本中的注释行。然而,shell脚本文件的第一行是......
  • 你会PHP、JAVA、Python或GO吗?都有做过哪些应用呢?
    PHP、Java、Python和Go都是广泛应用的编程语言,它们各自在不同的领域和场景中发挥着重要的作用。以下是它们各自的一些典型应用:PHPPHP是一种流行的服务器端脚本语言,特别适用于Web开发。以下是PHP的一些主要应用:电商:PHP是亚马逊网站的服务器端语言,用于处理订单、客户管理和产品......
  • 《JAVA编程思想》第四版 PDF 下载 中文版和英文版 高清PDF扫描带书签
     转载自:https://www.cnblogs.com/buwuliao/p/8073211.html非常感谢也可见:https://www.cnblogs.com/ChaoJieLiu/p/12910447.html一、链接:中文版+英文版+思维导图:链接:https://pan.baidu.com/s/1bmgOdC7gFhI4Waac6JV4Wg提取码:s3vc复制这段内容后打开百度网盘手机App,操作更方......
  • JavaScript 编程精解(Eloquent)第四版·翻译完成
    JavaScript编程精解(Eloquent)第四版第一章:引言第一部分:语言第二章:值、类型和运算符第三章:程序结构第四章:函数第五章:数据结构:对象和数组第六章:高阶函数第七章:对象的秘密生活第八章:项目:一个机器人第九章:漏洞和错误第十章:正则表达式第十一章:模......
  • Python中的map函数
    Python中的map函数是一种常用的高雅实现,它能够在不使用第三方库的情况下对一个列表进行映射,并返回一个新的列表。map函数不仅能够提高Python代码的可读性,还能够拓展Python的功能,使其成为一种强大的数据处理工具。Python中的map函数在Python中,map函数是map函数的别名。它是......
  • [编程笔记] 系统日期格式引起的bug
    系统获取的日期格式不对,导致程序出现异常,出现过多次了,这里记录一下。起因是测试说某个跟日期相关的活动,在他环境里失效,而我们开发本地测试了多遍都是正常的,这就很奇怪了,有种想给他重装系统的念头,哈哈。经过一系列的分析和排查,发现是他本地系统设置的日......
  • python连接操作oss对象存储
    用python调试一下oss对象存储。一开始用的oss2库,发现不行。用boto3库才可以,说明我的对象存储是和AWS兼容的,并不是基于阿里的oss.importboto3frombotocore.exceptionsimportNoCredentialsError,PartialCredentialsError#设置您的AccessKey和SecretKeyaccess_key_id......