• 线程


    线程:

    在操作系统中,每一个进程都有一个空间,而且每一个空间都有一个线程,进程是资源单位,代码的运行过程指的是线程(即进程运行指开辟空间存放资源,线程运行,cpu运行代码块),进程是线程的容器,一个进程内可以有多个线程,多个线程之间可以达到并发执行,线程是程序中一个单子执行单元,所以在启用上比进程快100

    线程----------------->单指代码的执行过程

    进程----------------->资源的申请与销毁的过程

    开启线程有两种方式,整体跟进程差不多:

    多个子线程也都是线程,因为都是主线程下的分支

    线程可以不用main因为所有的线程都是共享一个进程下的资源

    方案一:函数方案
    class MyThread(Thread):
        def run(self):#跟进程一样都有一个函数名run
            print("%s is runnong"%self.name)
            time.sleep(2)
            print("%s is done" %self.name)
    if __name__ == '__main__':
        t=MyThread()
        t.start()
        print("")
    方法二:自定义类

    进程vs线程:

    from threading import Thread
    from multiprocessing import Process
    import os,time
    
    def task():
        print("%s is running" %os.getpid())
        time.sleep(2)
        print("%s is done"%os.getpid())
    if __name__ == '__main__':
        t=Thread(target=task)
        t.start()
        # t.join()
        print("主线程",os.getpid())
        #线程中主线程的ID跟子线程的ID一样,先走子线程再走主线程
        """
        打印结果
         15592 is running
         主线程 15592
         15592 is done
        """
    
    
    def done():
        print("%s is running" %os.getpid())
        time.sleep(2)
        print("%s is done"%os.getpid())
    if __name__ == '__main__':
        p=Process(target=done)
        p.start()
        print("主进程",os.getpid())
        #进程中主线程的ID跟子进程的ID不一样,先走主进程再走子进程
        """
        打印结果
        主进程 10004
        7084 is running
        7084 is done
    
        """

    进程与线路共享情况:

    from threading import Thread
    from multiprocessing import Process
    import os
    n=100
    def work():
        global n
        n=0
    
    if __name__ == '__main__':
        p=Process(target=work)
        p.start()
        p.join()
        print("主进程",n)
        #子进程将n改为0,但仅仅改变了子进程的指,但是父进程的n依然还是100
    
        t=Thread(target=work)
        t.start()#创造子线程
        t.join()
        print("主线程",n)
        #查看结果为0,因为同一进程内的线程之间共享进程内的数据

    1、内存共享or隔离

    多个进程内存空间彼此隔离

    同一个进程下的多个线程共享,该进程内的数据

    2、创建速度

    造线程的速度比造进程的速度快

    线程比进程开启快的原因在于进程开去需要向操作系统发送信号,而线程不需要像进程那样去向操作系统发送信号,而是可以直接执行

    3、主与子ID是否相同

    进程中主进程与子进程ID不相同,进程中先走主进程再走子进程

    线程中主线程与子线程ID相同,线程中先走子线程,再走主线程

    守护线程:

    from threading import Thread
    import time
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    
    def bar():
        print(456)
        time.sleep(3)
        print("end456")
    
    
    t1=Thread(target=foo)
    t2=Thread(target=bar)
    
    t1.daemon=True
    t1.start()
    t2.start()
    print("main-------")
    
    '''
    123
    456
    main-------
    end123
    end456
    
    '''

    守护线程会在本进程内所有非守护线程都死掉了才跟着死

    守护线程其实守护的是整个进程的运行周期(线程内所有的非守护线程都运行完毕)

    互斥锁:

    from threading import Thread,Lock
    import time
    x=100
    mutex=Lock()
    def task():
        global x
        temp=x
        time.sleep(1)#在有等待的地方,如果main下面没有join()会打印出错
        x=temp-1
    if __name__ == '__main__':
        t=Thread(target=task)
        t.start()
        t.join()
        print(x)

    在线程中,加入时间睡眠后,如果不运用join()就会影响测试结果,因为计算在睡眠的下面,遇到睡眠后会先打印main下面的主线程printx,也就造成了输入为100的打印结果,加上join()后(主线程要等待子线程运行完毕后再运行)得到的值是正确的99

    from threading import Thread
    import time
    
    x = 100
    def task():
        global x
        temp = x
        time.sleep(1)
        temp -= 1
        x=temp
    if __name__ == '__main__':
        tlst=[]
        for i in range(100):
            t = Thread(target=task)
            tlst.append(t)
            t.start()
            for i in range(len(tlst)):
                tlst[i].join()
            print(x)

    通过放慢的方式可以看出,如果没有join()的情况下直接是显示100,在有join()等待子线程结束完毕之后再运行主线程是正确的显示

    from threading import Thread,Lock
    import time
    x=100
    mutex=Lock()
    def task():
        time.sleep(0.1)
        global x
        with mutex:
            x -= 1
    if __name__ == '__main__':
        for i in range(100):#循环次数
            t = Thread(target=task)
            t.start()
            t.join()
            print(x)
    加互斥锁版本
    from threading import Thread,current_thread,active_count,enumerate
    import time
    def task():
        print("%s 子线程原名" %current_thread().name)
        time.sleep(1)
        print("%s 子线程修改过后名字" %current_thread().name)
    if __name__ == '__main__':
        t=Thread(target=task)
        t.start()
        t.join()
        # print("判断线程是否存活",t.is_alive())
        # print("显示主线程名字",current_thread().getName())
        # print(t.name)#看当前线程的名字
        # print("显示存活的线程数",active_count())
        # print("将所有线程放入列表",enumerate())
        # current_thread().setName("主线程")#修改主线程名字
        # print("parent",current_thread().name),"我原名MainThread,现名主线程")
    了解点:
    from threading import Thread,Lock,active_count
    import time
    mutexA = Lock()
    mutexB = Lock()
    class MyThread(Thread):
        def run(self):
            self.f1()
            self.f2()
        def f1(self):
            mutexA.acquire()
            print("A")
            mutexB.acquire()
            print("B")
            mutexB.release()
            mutexA.release()
        def f2(self):
            mutexB.acquire()
            print("A")
            time.sleep(1)
            mutexA.acquire()
            print("B")
            mutexA.release()
            mutexB.release()
    if __name__ == '__main__':
        for i in range(10):
            t = MyThread()
            t.start()
        print(active_count())
    死锁现象和递归锁
    from threading import Thread, active_count, RLock
    import time
    obj = RLock()
    mutexA = obj
    mutexB = obj
    class MyThread(Thread):
        def run(self):
            self.f1()
            self.f2()
        def f1(self):
            mutexA.acquire()
            print("A")
            mutexB.acquire()
            print("B")
            mutexB.release()
            mutexA.release()
        def f2(self):
            mutexB.acquire()
            print("A")
            time.sleep(1)
            mutexA.acquire()
            print("B")
            mutexA.release()
            mutexB.release()
    if __name__ == '__main__':
        for i in range(10):
            t = MyThread()
            t.start()
        print(active_count())

    信号量

    控制同一时间互斥锁的量,并且有人释放锁会有人马上拿到锁

    from threading import Thread, Semaphore, current_thread
    import time
    import random
    sm = Semaphore(5)
    def task():
        with sm:
            print("%s正在卫生间" % current_thread().name)
        time.sleep(random.random())
    if __name__ == '__main__':
        for i in range(20):
            t = Thread(target=task)
            t.start()
  • 相关阅读:
    equals比较对象
    解决打包时出现的Failed to verify bitcode
    苹果的MDM简介
    unable to boot the simulator,无法启动模拟器已解决
    利用NSCalendar类实现日期的比较
    服务器开启https协议
    解决NSTimer存在的内存泄漏的问题
    ipad和iphone的适配
    集成shareSDK错误总结(新浪微博)
    AFN解析器里的坑
  • 原文地址:https://www.cnblogs.com/yf18767106368/p/9306763.html
Copyright © 2020-2023  润新知