前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python基础(16)——进程&线程

Python基础(16)——进程&线程

作者头像
羊羽shine
发布2019-05-28 13:33:22
3500
发布2019-05-28 13:33:22
举报
文章被收录于专栏:Golang开发

进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。 第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。 第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。[3] 进程是操作系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。

进程的并行与并发

并行 : 并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑;(资源够用,比如三个线程,四核的CPU ) 并发 : 并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率。 区别: 并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器。 并发是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个session。

fork

程序执行到os.fork()时,操作系统会创建一个新的进程(子进程),然后复制父进程的所有信息到子进程中。然后父进程和子进程都会从fork()函数中得到一个返回值,在子进程中这个值一定是0,而父进程中是子进程的 id号。getpid()获取子进程、getppid()获取父进程。

代码语言:javascript
复制
import os

pid = os.fork()

if pid == 0:
    print('子进程id:', os.getpid())
else:
    print('父进程id:', os.getppid())
multiprocessing

target表示这个进程实例所调用对象,args表示调用对象的位置参数,args是一个元组形式,必须用逗号隔开。kwargs表示调用对象的关键字参数,kwargs的类型是字典形式,name表示为当前进程实例的别名;group大多数情况下用不到;

代码语言:javascript
复制
Process([group [, target [, name [, args [, kwargs]]]]])

p.start():启动进程,并调用该子进程中的p.run() p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁 p.is_alive():如果p仍然运行,返回True

代码语言:javascript
复制
from multiprocessing import Process
import os


def func(arg1):
    print(arg1)
    print("子进程:", os.getpid())
    print("子进程的父进程:", os.getppid())  ##查看父的进程父的进程


if __name__ == '__main__':
    p = Process(target=func, args=(54321,))  # 传单个参数需要加逗号
    p.start()
    print('*' * 10)
    print("父进程:", os.getpid())  ## 查看父进程
    print("父进程的父进程:", os.getppid())  ##查看父的进程父的进程
join的使用

p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程

代码语言:javascript
复制
from multiprocessing import Process
import time


def func(arg1, arg2):
    print('*' * arg1)
    time.sleep(2)
    print('*' * arg2)


if __name__ == '__main__':
    p = Process(target=func, args=(2, 3))  # 传单个参数需要加逗号
    p.start()
    p.join()#感知一个子进程的结束,将异步程序改为同步
    print('*' * 4)

打印结果:

代码语言:javascript
复制
**
***
****
Process的继承
代码语言:javascript
复制
from multiprocessing import Process
import os


class CustomProgress(Process):
    def run(self):
        print(os.getpid())


if __name__ == '__main__':
    p = CustomProgress()
    p.start()
线程threading
代码语言:javascript
复制
from threading import Thread
import time

num = 100

def workOne():
    global num
    for i in range(3):
        num += 1
        print("----1, num is %d---" % num)


def workTwo():
    global num
    for i in range(3):
        num += 2
        print("----2, num is %d---" % num)


if __name__ == "__main__":
    print("--star num is %d---" % num)
    t1 = Thread(target=workOne)
    t1.start()

    t2 = Thread(target=workTwo)
    t2.start()
    time.sleep(3)
    print("--finish num is %d---" % num)
互斥锁
代码语言:javascript
复制
# 创建锁
mutex = threading.Lock()

# 锁定
mutex.acquire()

# 释放
mutex.release()

需要注意的是如果在调用acquire对这个锁上锁之前。它已经被其他线程上了锁,那么此时acquire会堵塞,直到这个锁被解锁为止。 模拟售票

代码语言:javascript
复制
import threading
import time
import os

i = 50  # 初始化票数
lock = threading.Lock()  # 创建锁


def saleTickets():
    global i
    global lock
    while True:
        lock.acquire()  # 得到一个锁,锁定
        if i > 0:
            i -= 1  # 售票 售出一张减少一张
            t = threading.current_thread()
            print(t.getName(), ':now left tickets:', i)  # 剩下的票数
            time.sleep(1)
        else:
            print(" No more tickets")
            os._exit(0)  # 票售完   退出程序
        lock.release()  # 释放锁


if __name__ == "__main__":

    for k in range(10):
        new_thread = threading.Thread(target=saleTickets)
        new_thread.start()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.10.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 进程
    • 进程的并行与并发
      • fork
        • multiprocessing
          • join的使用
            • Process的继承
              • 线程threading
                • 互斥锁
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档