zoukankan      html  css  js  c++  java
  • 进程和线程概览

    一、进程和线程概论

    1.什么是进程?

    程序是存储在磁盘中的可执行的数据。
    进程可以看作是程序的一次执行,每个进程都有自己的内存空间和数据栈。
    进程间只能通讯,而不能直接共享信息。

    2.什么是线程?

    一个进程中可以有多个线程,一个进程中线程共享运行环境,也就是有相同的内存空间、数据栈等。
    比如你启动了一个python项目,允许同时100人访问,你就可以人为在python进程中,同时开了100个线程。
    虽然一个进程中的线程共享数据,但是每个线程都拥有自己的栈空间和执行队列。

    3.进程和线程的关系?

    进程和线程的最大区别在于操作系统对其不同的资源管理方式。

    一个程序至少有一个进程,一个进程至少有一个线程。
    一个进程的崩溃并不会影响其它进程的运行,但是如果一个线程崩溃掉了,当前进程中的线程都会崩掉,因为共享数据。

    从逻辑的角度来讲,多线程的意义在于,在一个应用程序中,有多个执行部分可以同时执行。
    但是操作系统并不会把多个线程当作单独的应用来对其调度、管理和资源控制。

    多线程共享数据,自然可以极大的提高程序的运行效率。
    多线程虽然开销小,但是不利于管理,线程则于其刚好相反,同时健壮性更强。

    4.并发与并行

    并行:物理上具备同一时刻处理多个任务的能力。
    并发:逻辑上具备同一时刻处理多个任务的能力。
    虽然说并发可以同时里处理多个任务,但是并不是一定要同时执行。

    并行一定发生在多核CPU上,并行是并发设计的理想模式。
    单核机器上的并发是通过间隔方式切换执行。
    单线程通过协程的方式实现并发,协程是主动切换任务来实现的。

    python由于GIL锁的缘故,只能实现并发而不能并行。

    二、进程和线程的开启方式

    1、进程

    方式1:

    from multiprocessing import Process
    import time
    
    def task1(num):
        print("开始执行任务task1")
        time.sleep(num)
        print("任务task1执行结束")
    
    def task2(num):
        print("开始执行任务task2")
        time.sleep(num)
        print("任务task2执行结束")
    
    if __name__ == "__main__":
        p1 = Process(target=task1,args=(5,))
        p2 = Process(target=task2,args=(3,))
        p1.start()
        p2.start()
        
    # 执行结果:
    # 开始执行任务task1
    # 开始执行任务task2
    # 任务task2执行结束
    # 任务task1执行结束

      方式2:

    from multiprocessing import Process
    import time
    
    class TestProcess(Process):
        def __init__(self,num):
            super().__init__()
            self.num = num
    
        def run(self):
            print("任务task开始执行")
            time.sleep(self.num)
            print("任务task执行结束")
        
    
    if __name__ == "__main__":
        my_process = TestProcess(5)
        my_process.start()

    2.线程

    方式1:

    from threading import Thread
    import time
    
    def task1(num):
        print("开始执行任务task1")
        time.sleep(num)
        print("任务task1执行结束")
    
    def task2(num):
        print("开始执行任务task2")
        time.sleep(num)
        print("任务task2执行结束")
    
    if __name__ == "__main__":
        p1 = Thread(target=task1,args=(5,))
        p2 = Thread(target=task2,args=(3,))
        p1.start()
        p2.start()

    方式2:

    from threading import Thread
    import time
    
    class TestThread(Thread):
        def __init__(self,num):
            super().__init__()
            self.num = num
    
        def run(self):
            print("任务task开始执行")
            time.sleep(self.num)
            print("任务task执行结束")
    
    
    if __name__ == "__main__":
        my_process = TestThread(5)
        my_process.start()

    三、锁

    1.进程同步锁

    上锁之后,将会串行,不会并发执行。

    from multiprocessing import Process,Lock
    import time
    
    def task1(num,lock):
        lock.acquire()
        print("开始执行任务task1")
        time.sleep(num)
        print("任务task1执行结束")
        lock.release()
    
    def task2(num,lock):
        lock.acquire()
        print("开始执行任务task2")
        time.sleep(num)
        print("任务task2执行结束")
        lock.release()
    
    if __name__ == "__main__":
        lock = Lock()
        p1 = Process(target=task1,args=(5,lock))
        p2 = Process(target=task2,args=(3,lock))
        p1.start()
        p2.start()

    四、进程池和线程池

    1.进程池

    from concurrent.futures import ProcessPoolExecutor
    import os,random,time
    def func(name):
        print("%s吃了又一碗饭:%s" %(name,os.getpid()))
        time.sleep(random.randint(1, 3))
    
    if __name__ == "__main__":
        p = ProcessPoolExecutor(3)  #创建一个进程池,里面容纳3个进程
        for i in range(7):
            obj = p.submit(func,'科比%i'%i)
        p.shutdown(wait=True)  #类似与join,并且可以关门,以防在等的过程中又提交新的任务
        print("主进程")
        
    #执行结果:
    科比0吃了又一碗饭:13980
    科比1吃了又一碗饭:9636
    科比2吃了又一碗饭:12660
    科比3吃了又一碗饭:13980
    科比4吃了又一碗饭:12660
    科比5吃了又一碗饭:9636
    科比6吃了又一碗饭:13980
    主进程

    2.线程池

    from threading import Thread,current_thread
    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import time,os
    def task(n):
        print('%s is running'% current_thread().getName())
        time.sleep(3)
        return  n**2
    
    if __name__ =="__main__":
        t = ThreadPoolExecutor(3)   #默认是CPU的核数*5
        objs = []
        for i in range(7):
            obj = t.submit(task,i)
            objs.append(obj)
        t.shutdown(wait=True)  #异步,最终打印结果
        for obj in objs:
            print(obj.result())
        print("",current_thread().getName())
    
    
    执行结果:
    ThreadPoolExecutor-0_0 is running
    ThreadPoolExecutor-0_1 is running
    ThreadPoolExecutor-0_2 is running
    ThreadPoolExecutor-0_2 is running
    ThreadPoolExecutor-0_1 is running
    ThreadPoolExecutor-0_0 is running
    0
    1
    4
    ThreadPoolExecutor-0_1 is running
    9
    16
    25
    36
    主 MainThread

    五 、守护进程和守护线程

    无论是进程还是线程,当主进程结束的时候,守护进程也会随之结束。

    from multiprocessing import Process
    import os,time,random
    
    def task():
        print('%s is running '%os.getpid())
        time.sleep(2)
    
        print('%s is done' % os.getppid())
    
    if __name__ == "__main__":
        p = Process(target=task)
        p.daemon = True   #1.必须在进程开启之前  2.不能再开启子进程
        p.start()
        print("")
  • 相关阅读:
    Java基础课程---将一个字符串反转,将字符串中指定部分进行反转,比如,"abcdefg", 反转为"abfedcg"
    在Centon64位中卸载安装时系统自带的--openjdk,并且安装自己需要的jdk
    Java基础课程---sleep()方法 和 wait()方法的异同(面试题)
    Java基础课程---权限修饰符
    Java基础课程---
    MySQL 创建库
    brew
    android webview load 本地文件需要注意的地方
    android下隐藏标题栏
    android webview无法加载网页
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/11289248.html
Copyright © 2011-2022 走看看