zoukankan      html  css  js  c++  java
  • 线程

    1  什么是线程

      进程:资源单位    #车间

      线程:实际执行单位  #车间里面的实际工作的流水线 需要资源就问进程要

      注意:每一个进程中都会自带一个线程(人为命名为:主线程)

    2  为什么要有线程

      开一个线程:

        申请内存空间  耗时

        将代码拷贝到申请的内存空间中  耗时

      开线程:

        不需要申请内存空间

        #开启线程的速度非常快,几乎代码执行完线程就已经开启

      开线程的开销远远小于开进程的开销!!

    3  如何使用线程

      1 线程理论:

        进程:资源单位

        线程:实际执行单位

      2 创建线程的两种方式:

        ① 定义方法Thread(target=task, args=('egon',))

        ② 定义一个类 继承Theread  定义__init__为保证安全先super().__init__() 

         必须有run方法

      3 join方法

        主线程等子线程结束

      4 线程对象的其他属性和方法

        active_count()   当前存活的线程数

        current_thread().name  当前线程的名字

        os.getpid()   进程号(主线程,子线程指向的都是同一个进程号的pid)

      5 守护线程:

        线程启动前用daemon=True 声明

      6 线程间数据是否隔离?

        线程之间数据是共享

          多个线程操作同一份数据 会出现数据不安全的情况

          涉及到多个线程或进程操作同一份数据的时候,通常都需要将 并行 并发 变成串行

          虽然牺牲了效率 但是提高了数据的安全性

          针对不同的数据,需要加不同的锁

          锁(独立卫生间)

      7 线程互斥锁

    开启线程的两种方式
    开启线程的两种方式:
    方式1:
    
    from threading import Thread
    import time
    
    
    def task(name):
        print('%s is running' % name)
        time.sleep(1)
        print('%s is over' % name)
    
    
    if __name__ == '__main__':
        t = Thread(target=task, args=('egon',))
        t.start()       #开启线程的速度非常快,几乎代码执行完线程就已经开启
        print('')      #主线程结束后 不会立即结束进程,会等待所有的 非守护线程都结束完(非守护线程还要用进程的资源)才结束。
                        #就像主线程用完作业完后需要关闭车间的电,但是车间里别的流水线还要用电 所以不能立即停电
    
    
    egon is running主
    
    egon is over
    
    
    
    方式二:
    from threading import Thread
    import time
    
    
    class MYThread(Thread):
        def __init__(self, name):
            super().__init__()
            self.name = name
    
        def run(self):
            print('%s is running ' % self.name)
            time.sleep(1)
            print('%s is over ' % self.name)
    
    
    if __name__ == '__main__':
        t = MYThread('jack')
        t.start()
        print('')
    
    jack is running 主
    
    jack is over 

    线程对象的其他属性和方法

    线程对象的其他属性和方法:
    from threading import Thread,active_count,current_thread
    import os
    import time
    
    def task(name):
        print('%s is running'%name,os.getpid(),current_thread().name)
        time.sleep(1)
        print('%s is over'%name)
    
    # def info(name):
    #     print('%s is running'%name,current_thread().name)
    #     time.sleep(1)
    #     print('%s is over'%name)
    
    t=Thread(target=task,args=('name',))
    t.start()
    t.join()
    print(active_count())   #当前存活的线程数
    print(os.getpid())
    print(current_thread().name)
    
    name is running 5128 Thread-1   #子线程 5128 子线程名字
    name is over                    #name is over  
    1                               #当前存活的线程数 1
    5128                            #5128
    MainThread                      #主线程名字

    守护线程

    from threading import Thread
    import time
    
    
    def task(name):
        print('%s is running' % name)
        time.sleep(1)
        print('%s is over' % name)
    
    
    if __name__ == '__main__':
        t = Thread(target=task, args=('小王',))
        t.daemon = True
        t.start()
        print('')
    
    小王 is running主

    线程间数据是共享的

    #线程之间数据共享
    
    from  threading import Thread
    x=100
    def task():
        global x
        x=666
    
    t=Thread(target=task)
    t.start()
    t.join()    #等待子线程 结束后再查看
    print(x)    #666

    线程互斥锁

    线程互斥锁:
    from  threading import Thread,Lock
                            #线程    锁
    import time
    
    mutex=Lock()
    n=100
    
    def task():
        global n
        mutex.acquire() #抢锁
        tem=n
        time.sleep(0.1)
        n=tem-1
        print(n)    #99 98 97 96....0
        mutex.release() #释放锁
    
    t_list=[]
    for i in range(100):
        t=Thread(target=task)
        t.start()       #启动子线程
        t_list.append(t)      #把子线程对象添加到列表里
    
    for t in t_list:
        t.join()    #等所有的子线程结束完 才进行下面代码
    
    print('',n)    #最后主线程是0
  • 相关阅读:
    [LeetCode] 1081. Smallest Subsequence of Distinct Characters 不同字符的最小子序列
    [LeetCode] 1080. Insufficient Nodes in Root to Leaf Paths 根到叶路径上的不足节点
    [LeetCode] 1079. Letter Tile Possibilities 活字印刷
    [LeetCode] 1078. Occurrences After Bigram 双元语法分词
    [LeetCode] 1074. Number of Submatrices That Sum to Target 元素和为目标值的子矩阵数量
    [LeetCode] 1073. Adding Two Negabinary Numbers 负二进制数相加
    [LeetCode] 1072. Flip Columns For Maximum Number of Equal Rows 按列翻转得到最大值等行数
    [LeetCode] 1071. Greatest Common Divisor of Strings 字符串的最大公因子
    [LeetCode] 1054. Distant Barcodes 距离相等的条形码
    [LeetCode] 1053. Previous Permutation With One Swap 交换一次的先前全排列
  • 原文地址:https://www.cnblogs.com/lakei/p/10827402.html
Copyright © 2011-2022 走看看