zoukankan      html  css  js  c++  java
  • 并发编程之多线程篇之一

    本节主要知识点包括三个方面

      一、线程的含义

      二、进程和线程的区别

      三、开启进程的两种方式

    1️⃣ 什么是线程和多线程?

      1、在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程。

      线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于cpu),

      而一条流水线必须属于一个车间,一个车间的工作过程是一个进程,车间负责把资源整合到一起,

      是一个资源单位,而一个车间内至少有一条流水线。

      注意:进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。

      2、多线程(即多个控制线程)的概念是,在一个进程中存在多个线程,多个线程共享该进程的地址空间,

          相当于一个车间内有多条流水线,都共用一个车间的资源。

    2️⃣ 线程与进程的区别  

      归根结底,线程和进程的区别包括以下两点,这也是我们在特定的场景下需要使用多线程的原因:

    1. 同一个进程内的多个线程共享该进程内的地址资源
    2. 创建线程的开销要远小于创建进程的开销(创建一个进程,就是创建一个车间,涉及到申请空间,而且在该空间内建至少一条流水线,但创建线程,就只是在一个车间内造一条流水线,无需申请空间,所以创建开销小)
    3. 多线程举例

                开启一个字处理软件进程,该进程肯定需要办不止一件事情,比如监听键盘输入,处理文字,

        定时自动将文字保存到硬盘,这三个任务操作的都是同一块数据,因而不能用多进程。只能在一个

        进程里并发地开启三个线程,如果是单线程,那就只能是,键盘输入时,不能处理文字和自动保存,

        自动保存时又不能输入和处理文字。

      4、多线程和多进程的区别

        4.1 在主进程下开启线程

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    
    import time
    from multiprocessing import Process,current_process
    from threading import Thread
    import os
    
    def task():
        print('线程2:%s'%(os.getpid()))
    
    if __name__ == '__main__':
        t = Thread(target=task)
        t.start()
        print('线程1:%s'%os.getpid())
    '''几乎是t.start() 的同时就将线程开启了,然后执行打印,可见开线程开销极小。 线程2:2708 线程1:2708 '''

        4.2 在主进程下开启子进程

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    
    import time
    from multiprocessing import Process,current_process
    from threading import Thread
    import os
    
    
    def task():
    #print(current_process().pid) # 8180
    print('子进程:%s,父进程:%s'%(os.getpid(),os.getppid()))

    if __name__ == '__main__':
    p1 = Process(target=task)
    p1.start()
    #print('主进程',current_process().pid) # 主进程 1840
    print('主进程:%s'%os.getpid())

    主进程:5900
    子进程:3760,父进程:5900

    # p.start ()将开启进程的信号发给操作系统后,操作系统要申请内存空间,让好拷贝父进程地址空间到子进程,开销远大于线程

          

    还能归结出以下三点:

       1、开进程开销远大于开线程。
            2、在主进程下开启多个线程,每个线程都跟主进程的pid一样;多个进程,每个进程都有不同的pid;

       3 、同一进程的多个线程共享该进程的地址空间。

    3️⃣ 开启进程的两种方式

      3.1 回顾开多进程

    from multiprocessing import Process
    import time
    import random
    
    def task(name):
      for i in range(2):
            print('%s运行%s'%(name,i))
            time.sleep(random.randrange(1,3))
    
    if __name__ == '__main__':
        p = Process(target=task,args=('子进程',))
        p.start()
        print('主进程')

      3.2 开启多线程方式一:

    import time
    import random
    from threading import Thread
    
    def producer(name):
        for i in range(3):
            print('%s 启动运行%i'%(name,i))
            time.sleep(random.randrange(1,3))
    
    if __name__ == '__main__':
        # 实例化对象
        t = Thread(target=producer,args=('线程',)) # 括号内必须加逗号
        # 调用对象方法
        t.start()
        print('进程') # 开启进程就相当于在内存里开辟了一块内存空间,具体由线程来执行

      3.3 开启多线程方式二:

    class MyThread(Thread):
        def __init__(self,name):
            super().__init__()
            self.name = name
    
        def run(self): # 必须是run方法(默认的)
            for i in range(3):
                print('%s 开始运行%s'%(self.name,i))
                time.sleep(random.randrange(1,3))
    if __name__ == '__main__':
        t = MyThread('线程')
        t.start()
        print('进程开启')
    '''运行结果:
    线程 开始运行0
    进程开启
    线程 开始运行1
    线程 开始运行2
    '''

      总结:

    1、每启动一个进程,这个进程内至少得有一个线程。
    2、进程本身只是一个资源单位,并不是真正执行,进程内的线程才是执行单位。
    3、一个进程内可以有多个线程,且进程在内存中相互隔离,而同一个进程内的线程是共享资源的,各线程之间地位是平等的。
    4、进程更消耗资源,而线程开销小,是在已有的进程内占用。
  • 相关阅读:
    数据库管理 trove openstack
    Vmware 给虚拟机传脚本并执行
    Vmware 控制脚本
    python 脚本之 IP地址探测
    python 模块之-ffmpeg 中文参数对照表
    VMware ezmomi工具使用
    VS编译器从DLL导出模板类
    Qt5+VS2012编程
    Visual Studio 2012优化
    计算几何
  • 原文地址:https://www.cnblogs.com/schut/p/9017264.html
Copyright © 2011-2022 走看看