pythonx4-多线程01

多线程

  1. 什么是线程,进程

    a. 在实现了线程的操作系统中,线程是操作系统能够运算调度的最小单位.

    b. 线程被包含在进程中,是进程的实际运作单位.

    c. 一个程序的执行实例就是一个进程.

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.

  2. 进程和程序的关系: 进程是线程的容器.

    Linux进程有父进程和子进程之分,windows的进程是平等关系.

    线程有时称为轻量级进程,一个标准的线程由线程ID,当前指令指针,寄存器集合和堆栈组成.

    当运行一个程序时,OS会创建一个进程。它会使用系统资源(CPU、内存和磁盘空间)和OS内核中的数据结构(文件、网络连接、用量统计等)。

    进程之间是互相隔离的,即一个进程既无法访问其他进程的内容,也无法操作其他进程。

    操作系统会跟踪所有正在运行的进程,给每个进程一小段运行时间,然后切换到其他进程,这样既可以做到公平又可以响应用户操作。

    可以在图形界面中查看进程状态,在在Windows上可以使用任务管理器。也可以自己编写程序来获取进程信息。

  3. 总结

    对线程、线程的理解:

    1. 进程是独立的王国,进程间不能随便共享数据.

    2. 线程是省份,同一进程内的线程可以共享进程的资源,每一个线程有自己独立的堆栈.

    线程的状态:

    • New新建 :新创建的线程经过初始化后,进入Runnable状态。

    • Runnable就绪:等待线程调度。调度后进入运行状态。

    • Running运行:线程正常运行

    • Blocked阻塞:暂停运行,解除阻塞后进入Runnable状态重新等待调度。

    • Dead消亡:线程方法执行完毕返回或者异常终止。

      thread.png

可能有3种情况从Running进入Blocked:

  1. 单线程

     from time import ctime,sleep
    
     def music():
         for i in range(2):
             print("I was listening to music. %s" %ctime())
             sleep(1)
     
     def move():
         for i in range(2):
             print("I was at the movies! %s" %ctime())
             sleep(5)
     
     if __name__ == '__main__':
         music()
         move()
         print("all over {}".format(ctime()))
    
  2. 什么是多线程

    多线程类似于同时执行多个不同程序,多线程运行有如下优点:

    • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
    • 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
    • 程序的运行速度可能加快
    • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

    每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。
    指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。

  3. 创建线程对象

    Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。

    由于任何进程默认就会启动一个线程,我们把该线程称为主线程,主线程又可以启动新的线程,Python的threading模块有个current_thread()函数,它永远返回当前线程的实例。主线程实例的名字叫MainThread,子线程的名字在创建时指定,如果不起名字Python就自动给线程命名为Thread-1,Thread-2……

    threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。python当前版本的多线程库没有实现优先级、线程组,线程也不能被停止、暂停、恢复、中断。

    threading模块提供的类:

    Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。

threading 模块提供的常量:

  threading.TIMEOUT_MAX     #设置threading全局超时时间。

threading的属性和方法
    
1. current_thread()  # 返回当前线程对象.
    
2. main_thread()  # 返回主线程对象.
    
3. active_count()  # 当前处于alive状态的线程个数.
    
4. enumerate()  # 返回所有活着的线程的列表,不包括已经终止的线程和未开始的线程.
    
5. get_ident()  # 返回当前线程ID,非0整数.

thread实例(线程对象)的属性和方法(下面还有补充哦)

1. name: 只是一个名称标识,可以重名, getName()、setName()来获取、设置这个名词。

2. ident: 线程ID, 它是非0整数。线程启动后才会有ID,否则为None。线程退出,此ID依旧可以访问。此ID可以重复使用。

3. is_alive(): 返回线程是否活着。
  1. 开启线程的两种方式-函数
    def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)
        pass
* target: 线程调用的对象,就是目标函数.
* name: 为线程起个名字.
* args: 为目标函数传递实参, 元组.
* kwargs: 为目标函数关键字传参, 字典.

demo 1:
    
    def func(n):  # 定义每个线程要运行的函数
        while n > 0:
            print("当前线程数:", threading.activeCount())
            print("当前线程:", threading.current_thread())
            n -= 1
    
    
    for x in range(5):
        t = threading.Thread(target=func, args=(2,))  # 生成一个线程实例,生成实例后 并不会启动,需要使用start命令
        t.start()  # 启动线程
    
    print("主线程:", threading.current_thread().name)
    
>demo1中print("主线程:", threading.current_thread().name)处于主线程中,我们可以发现主线程并没有等到所有其他线程执行完才执行。对于这个进程来说内部所有线程地位相等

        
demo 2:

        import threading
        import time
        #方法一:将要执行的方法作为参数传给Thread的构造方法
        
        def action(arg):
            time.sleep(1)
            print(threading.current_thread())
        
            print('the arg is:{0}'.format(arg))
        
        for i in range(4):
            t =threading.Thread(target=action,args=(i,))
            t.start()
        
        if __name__ == '__main__':
            print(threading.current_thread())
            print('main thread end!')
            
**线程退出**

python没有提供线程退出的方法,在下面情况时会退出:
    
1. 线程函数内语句执行完毕.
2. 线程函数中抛出未处理的异常.

        import threading
        import time
        def worker():
            count = 0
        
            try:
                while True:
                    if (count > 5):
                        raise RuntimeError('error happened')
        
                        # return
        
                    time.sleep(1)
        
                    print("I'm working")
        
                    count += 1
            except RuntimeError as ex:
                print(ex)
        
        
        t = threading.Thread(target=worker, name='worker')  # 线程对象.
        
        t.start()  # 启动.        
  1. 开启线程的两种方式-用类来包装线程对象

    start(): 启动线程。每一个线程必须且只能执行该方法一次。

    run(): 运行线程函数。

    start()方法会调用run()方法,而run()方法可以运行函数。

demo 1:

    class MyThread(threading.Thread):
        def __init__(self,arg):
            super(MyThread, self).__init__()#注意:一定要显式的调用父类的初始化函数。
            self.arg=arg
        def run(self):#定义每个线程要运行的函数
            time.sleep(1)
            print 'the arg is:%s\r' % self.arg
    
    for i in xrange(4):
        t =MyThread(i)
        t.start()

demo 2:
    
    import threading

    import time
    
    
    def worker():
        count = 0
    
        while True:
    
            if (count >= 5):
                break
    
            time.sleep(1)
    
            count += 1
    
            print('worker running')
    
    
    class MyThread(threading.Thread):
    
        def start(self):
            print('start~~~~~~~~~~~~~')
    
            super().start()
    
        def run(self):
            print('run~~~~~~~~~~~~~~~~~')
    
            super().run()
    
    
    t = MyThread(name='worker', target=worker)

    #t.strat()
    t.run()
    
**注意**

**使用start方法启动线程,启动了一个新的线程,名字叫做worker running,但是使用run方法启动的线程,并没有启动新的线程,只是在主线程中调用了一个普通的函数而已。**

**因此,启动线程要使用start方法,才能启动多个线程。**
Thread类

构造方法: 
* Thread(group=None, target=None, name=None, args=(), kwargs={}) 

* group: 线程组,目前还没有实现,库引用中提示必须是None;
   
* target: 要执行的方法; 
  
* name: 线程名; 
  
* args/kwargs: 要传入方法的参数。

实例方法: 

* isAlive(): 返回线程是否在运行。正在运行指启动后、终止前。 
* get/setName(name): 获取/设置线程名。 
* start():  启动线程。每一个线程必须且只能执行该方法一次。线程准备就绪,等待CPU调度
* run(): 运行线程函数。
* join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容

  • 一文读懂Python多线程 1、线程和进程 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运...
    星丶雲阅读 1,433评论 0 4
  • 线程 操作系统线程理论 线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有...
    go以恒阅读 1,625评论 0 6
  • 环境 xubuntu anaconda pycharm python https://www.cnblogs.co...
    Ericoool阅读 1,886评论 0 0
  • Python 多线程 多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序...
    今早上阅读 344评论 0 0
  • 今天看中央记录频道《少林功夫2》,看着感想颇多。 真功夫在民间吗?民间又如何去传承!大环境在变,人心在变,传承看起...
    慧心学堂hx助力梦想阅读 572评论 0 1