zoukankan      html  css  js  c++  java
  • 小白学Python---进程和线程

    进程和线程的由来

    进程

       为了提高批处理操作系统的效率,人们发明了进程,用进程来对应一个程序,每个进程来对应一定的内存地址空间,并且只能使用它自己的内存空间,各个进程之间互不干扰。进程同时也保存了程序每个时刻的运行状态,为进程切换提供了可能。当进程暂停时,它会保存当前进程的状态(进程标识,进程使用的资源等),在下一次切换回来时根据之前保存的状态进行恢复,接着继续执行。进程让操作体统的并发成为了可能。虽然并发从宏观上看有多个任务在执行,但在事实上,对于单核CPU来说,任意具体时刻都只有一个任务在占用CPU资源。
    

    线程

       出现了进程之后,操作系统的性能得到了大大的提升。虽然进程的出现解决了操作系统的并发问题,但是人们不满足,逐渐对实时性有了要求。因为一个进程在一个时间段内只能做一个事情,如果一个进程有多个子任务时,只能逐个得执行这些子任务,很影响效率。为了处理这种情况,人们发明了线程,让一个线程执行一个子任务,这样一个进程就包含了多个线程,每个线程负责一个单独的子任务。
    

    进程和线程的区别

    最大的区别是:是否单独占有内存地址空间
    

    (1)进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
    (2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进行至少包括一个线程。
    (3)进程的创建调用fork或者vfork,而线程的创建调用pthread_create,进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
    (4)线程是轻两级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
    (5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
    (6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志。(参考:https://blog.csdn.net/zhou753099943/article/details/51771220)

    python中实现多进程和多线程

    import time
    from multiprocessing import Process
    
    
    def output():
        count = 0
        while count < 30:
            print('a', end=' ', flush=True)
            count += 1
            time.sleep(0.2)
        print('%d个a' % count)
    
    
    def main():
        Process(target=output).start()
        count = 0
        while count < 30:
            print('b', end=' ',flush=True)
            count += 1
            time.sleep(0.2)
        print('%d个b' % count)
    
    
    if __name__ == '__main__':
        main()
    

    创建线程的方式:1、直接创建Thread对象并通过target参数指定线程启动后要执行的任务。2、继承Thread自定义线程,通过重写run方法指定线程启动后执行的任务。

    from threading import Thread
    
    #count是全局变量,只有一个,inner_count每个线程有一个
    count = 0
    def output(string):
        global count
        inner_count = 0
        while count < 100:
            print(string, end='', flush = True)
            count += 1
            inner_count += 1
        print('
    %s打印了%d次
    ' % (string, inner_count))
    
    
    def main():
        #output不能加括号
        #daemon是守护线程,不值得保留的线程,其他线程如果都结束了,守护线程也自动结束
        Thread(target=output, args=('ping'), daemon=True).start()
        Thread(target=output, args=('pong',),daemon=True).start()
    
    if __name__ == '__main__':
        main()
    

    无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁 需要强调的是:运行完毕并非终止运行

      #1.对主进程来说,运行完毕指的是主进程代码运行完毕.主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束。
    
      #2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕。主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。
    

    多线程在游戏中的应用:赛车

    from random import randint
    from threading import Thread
    from time import sleep
    import pygame
    
    
    class Color(object):
        BLACK = (0, 0, 0)
        WHITE = (255, 255, 255)
        GRAY = (242, 242, 242)
    
        @staticmethod
        def random_color():
            r = randint(0, 255)
            g = randint(0, 255)
            b = randint(0, 255)
            return r, g, b
    
    
    class Car(object):
    
        def __init__(self, x, y, color):
            self._x = x
            self._y = y
            self._color = color
    
        def move(self):
            if self._x + 60 <= 950:
                self._x += randint(1, 10)
    
        def draw(self, screen):
            pygame.draw.rect(screen, self._color, (self._x, self._y, 60, 30), 0)
    
    
    def main():
        class BackgroundTask(Thread):
    
            def run(self):
                while True:
                    screen.fill(Color.GRAY)
                    pygame.draw.line(screen,Color.BLACK,(130, 0),(130, 600),4)
                    pygame.draw.line(screen,Color.BLACK,(950, 0),(950, 600),4)
                    for car in cars:
                        car.draw(screen)
                    pygame.display.flip()
                    sleep(0.05)
                    for car in cars:
                        car.move()
        cars = []
        for index in range(5):
            temp = Car(70 , 50+ 120 * index, Color.random_color())
            cars.append(temp)
        car1 = Car(70, 50, Color.random_color())
        pygame.init()
        screen = pygame.display.set_mode((1000, 600))
        BackgroundTask(daemon=True).start()
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
    
        pygame.quit()
    
    
    if __name__ == '__main__':
        main()
    
    

    推荐:更多关于进程和线程的知识可以查看骆昊老师博客: https://blog.csdn.net/jackfrued/article/details/79717727

  • 相关阅读:
    分享:CodeLite 5.1 发布,C++ 集成开发环境
    Elementary Sockets:readn, writen, and readline Functions
    How to handle boost::iostreams::gzip_dec C++ Forum
    分享:python/c++ 深拷贝与浅拷贝(转)写∽好
    我刚刚通过 @盛大网盘EverBox 分享了 Web协议与实践HTTP.、网络协议、缓存技术和....pdf, 欢迎大家下载!
    Is zlib threadsafe?
    print "\v"
    分享:混合编译c和cpp的makefile模板
    Elementary Sockets:readn, writen, and readline Functions
    c的socket教程 二进制 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/bbszc520/p/8638726.html
Copyright © 2011-2022 走看看