zoukankan      html  css  js  c++  java
  • 线程

    补充知识点:

    守护进程的例子

    from multiprocessing import Process
    import time,random
    
    
    def runing():
        print('123')
        time.sleep(random.randint(1,3))
        print('end 123')
    
    def runing1():
        print('456')
        time.sleep(random.randint(1,2))
        print('end 456')
    
    if __name__ == '__main__':
        p1=Process(target=runing)
        p2=Process(target=runing1)
    
        p1.daemon=True
        p1.start()
        p2.start()
    
        print('主进程==》')

    先说明一点,守护进程一定要在,strat之前加 不然会报错的,上面的例子 写了两个子进程,一个是守护进程,一个是普通的子进程,

    我们都知道主进程 要等子进程,结束后,替儿子收尸,而守护进程要伴随主进程一生,(一生指的是主进程的执行期间)那上面的例子,运行的顺序

    就是在主进程执行结束后,守护进程 就完成了自己的任务 死掉了,然后主进程一直等子进程死掉了,最后自己死掉了

    线程:

    1、什么是线程
        线程指的是一条流水线的工作过程

        进程根本就不是一个执行单位,进程其实是一个资源单位
        一个进程内自带一个线程,线程才是执行单位

    2、进程VS线程
        1、同一进程内的线程们共享该进程内资源,不同进程内的线程资源肯定是隔离的
        2、创建线程的开销比创建进程要小的多

    创建线程的两种方式

    from threading import Thread
    import time,random
    
    def lack(name):
        print('%s is runing'%name)
        time.sleep(random.randint(1,3))
        print('%s end'%name)
    
    if __name__ == '__main__':
        t=Thread(target=lack,args=('egon',))
        t.start()
        print('主线程--->')
    
    
    
    class Mythread(Thread):
        def run(self):
            print('%s is runing' % self.name)
            time.sleep(random.randint(1, 3))
            print('%s end' % self.name)
    
    if __name__ == '__main__':
        t=Mythread()
        t.start()
        print('主线程--->')

    线程没有主次之分,称为主线程 是为了更好的区分

    比较进程与线程的开销:

    from threading import Thread
    import time,os
    
    def task():
        print('%s is running' %os.getpid())
        time.sleep(3)
    
    if __name__ == '__main__':
        t=Thread(target=task,)
        t.start()
        print('主线程',os.getpid())
        #结果
        #10632 is running
        #主线程 10632
    from multiprocessing import  Process
    
    def task1():
        print('%s is running' % os.getpid())
        time.sleep(3)
    
    
    if __name__ == '__main__':
        p=Process(target=task1)
        p.start()
        print('主进程', os.getpid())
        #结果
        #主进程 18036
        #16560 is running
    #线程创建开销小
    

    因为创建子进程,需要向操作系统发送请求,在等操作系统,去创建内存空间,在拷贝一份主进程的所有数据 没有线程在同一进程内,直接建一条

    流水线来的快捷,所以创建进程比创建线程开销要大的多的多

    比较进程与线程的隔离性:每个进程在内存空间都是有一块独立的内存空间的,互相隔离,数据不能共享的,但是线程的数据是可以共享的,通过下面的例子我们来证明一下:

    #同一进程内的多个线程共享该进程内的资源
    
    from threading import Thread
    import time,os
    
    x=1000
    def task():
        global x
        x=0
    
    if __name__ == '__main__':
        t=Thread(target=task,)
        t.start()
        t.join()
        print('主线程',x)#主线程 0

    线程对象的其他方法

    from threading import Thread,current_thread,active_count,enumerate
    import time,os
    
    def task():
        print('%s is running' %current_thread().name)
        time.sleep(3)
    
    if __name__ == '__main__':
        t1=Thread(target=task,name='第一个线程')
        t2=Thread(target=task,)
        t3=Thread(target=task,)
        t1.start()
        t2.start()
        t3.start()
    
        # print(t1.is_alive())
        print(active_count())#活跃的线程个数
        print(enumerate())#以列表的形式 打印出活跃的线程
        print('主线程',current_thread().name)#相当于实例化一个对象,取到它的名字

    守护线程:

    from threading import Thread
    import time,random
    
    def lack(name):
        print('%s is runing'%name)
        time.sleep(random.randint(1,3))
        print('%s end'%name)
    
    if __name__ == '__main__':
        t=Thread(target=lack,args=('lxx',))
        t.daemon=True
        t.start()
        print('主线程--》')
    
    
    def runing():
        print('123')
        time.sleep(3)
        print('end 123')
    
    def runing1():
        print('456')
        time.sleep(1)
        print('end 456')
    
    if __name__ == '__main__':
        t1=Thread(target=runing)
        t2=Thread(target=runing1)
    
        t1.daemon=True
        t1.start()
        t2.start()
    
        print('主线程==》')

    守护进程和守护线程都是守护主的执行,但不一样的是主进程,print()执行就已经结束了,而主线程是除了守护线程以外的所有线程都执行完毕包括自己,才算执行完毕

    线程斥互锁

    from threading import Thread,Lock
    import time
    
    mutex=Lock()
    x=100
    
    def task():
        global x
        mutex.acquire()
        temp=x
        time.sleep(0.1)
        x=temp-1
        mutex.release()
    
    
    if __name__ == '__main__':
        start=time.time()
        t_l=[]
        for i in range(100):
            t=Thread(target=task)
            t_l.append(t)
            t.start()
        for t in t_l:
            t.join()
    
        print('',x)
        print(time.time()-start)

    死锁现象与递归锁

    from threading import Thread,Lock,RLock
    import time
    
    # mutexA=Lock()
    # mutexB=Lock()
    
    mutexA=mutexB=RLock()
    
    class MyThread(Thread):
        def run(self):
            self.f1()
            self.f2()
    
        def f1(self):
            mutexA.acquire()
            print('%s 拿到了A锁' %self.name)
    
            mutexB.acquire()
            print('%s 拿到了B锁' %self.name)
            mutexB.release()
    
            mutexA.release()
    
        def f2(self):
            mutexB.acquire()
            print('%s 拿到了B锁' %self.name)
            time.sleep(0.1)
    
            mutexA.acquire()
            print('%s 拿到了A锁' %self.name)
            mutexA.release()
    
            mutexB.release()
    
    
    if __name__ == '__main__':
        for i in range(10):
            t=MyThread()
            t.start()
    
        # t1=MyThread()
        # t1.start()
        #
        # t2=MyThread()
        # t2.start()
        #
        # t3=MyThread()
        # t3.start()
        print('')

    信号量

    # from multiprocessing import Semaphore
    
    from threading import Thread,Semaphore,current_thread
    import time,random
    
    sm=Semaphore(5)
    
    def go_wc():
        sm.acquire()
        print('%s 上厕所ing' %current_thread().getName())
        time.sleep(random.randint(1,3))
        sm.release()
    
    if __name__ == '__main__':
        for i in range(23):
            t=Thread(target=go_wc)
            t.start()

    互斥锁和递归锁,每次都只能一个人来抢,而且 信号量,可以自己设置几个人同时来抢 

  • 相关阅读:
    [C++]仿java.lang.String的字符串工具类[原]
    SQL基础1创建表、用户
    Linux中gdb 查看core堆栈信息
    Direct3D9基础工具类[原]
    eclipse3.4启动错误
    ndk连接第三方库
    数据库基本概念
    MySQL常见命令
    MySQL启动和停止
    MySQL配置文件
  • 原文地址:https://www.cnblogs.com/yftzw/p/8954388.html
Copyright © 2011-2022 走看看