• 线程,进程概念


    当多个客户端访问服务端的时候,每个客户端都会对服务端说:’嗨,我想连接你‘。服务端的sorcket通过while循环,一直监听着是否有client请求连接,当有请求(一个或者多个)连接过来的时候:就会分配(一个或者多个)进程或者线程给client,并保持连接,进行通话。

    线程是应用程序的最小单位,

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import threading
    import time
      
    def show(arg):
        time.sleep(2)
        print 'thread'+str(arg)
      
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))  #这里实例化对象的时候传的两个参数第一个参数是,线程需要执行的方法,第二个参数方法的参数
        t.start()
      
    print 'main thread stop'
    View Code

    上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。

    再次回顾:这里为什么是分片执行?

    python中的多线程,有一个GIL(Global Interpreter Lock 全局解释器锁 )在同一时间只有一个线程在工作,他底层会自动进行上下文切换.这个线程执行点,那个线程执行点!

    更多方法:请自己多查看源码,多看,多看,看不懂,再看。

    • start       线程准备就绪,等待CPU调度
    • setName     为线程设置名称
    • getName     获取线程名称
    • setDaemon   设置为后台线程或前台线程(默认)
    •             如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
    •             如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
    • join        逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
    • run         线程被cpu调度后执行Thread类对象的run方法

    线程锁:

    无线程锁:(多个线程同时对一个内存地址进行操作)
    #!/sur/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = 'ganzl'
    import threading
    import time
    gl_num = 0
    def show(arg):
        global gl_num
        time.sleep(1)
        gl_num +=1
        print gl_num
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    print 'main thread stop'
    View Code
    有线程锁:
    #!/sur/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = 'ganzl'
    import threading
    import time
    gl_num = 0
    lock = threading.RLock() #实例化调用线程锁
    def Func():
        lock.acquire() #获取线程锁
        global gl_num
        gl_num +=1
        time.sleep(1)
        print gl_num
        lock.release() #释放线程锁,这里注意,在使用线程锁的时候不能把锁,写在代码中,否则会造成阻塞,看起来“像”单线程
    
    for i in range(10):
        t = threading.Thread(target=Func)
        t.start()
    View Code

    event

    python线程的事件用于主线程控制其他子线程的控制。

    事件主要提供了三个方法 set、wait、clear。

    事件处理的机制:

      全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,

                  如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

    • clear:将“Flag”设置为False
    • set:将“Flag”设置为True
    #!/sur/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = 'ganzl'
    import threading
    def do(event):
        print 'start'
        event.wait() #执行对象weit方法,然后他们停下来,等待“Flag”为True
        print 'execute'
    event_obj = threading.Event() #创建事件的对象
    for i in range(2):
        t = threading.Thread(target=do, args=(event_obj,)) #执行多线程。
        t.start()
    print dir(event_obj)
    print event_obj.__dict__
    print event_obj.__dict__['_Event__flag']
    
    inp = raw_input('input:')
    if inp == 'true':
        event_obj.set()
        print event_obj.__dict__['_Event__flag']

    多进程:

    注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

    并且python不能再Windows下创建进程!(pycharm不能执行多线程的demo)

    并且在使用多进程的时候,最好是创建多少个进程?:和CPU核数相等

    Linux下,工作中用到的批量执行命令的demo:

    #!/sur/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = 'ganzl'
    import multiprocessing
    import sys,os,time
    import paramiko
    
    def ssh_cmd(host,port,user,passwd,cmd):
        msg = "-----------Result:%s----------" % host
        s = paramiko.SSHClient()
        s.load_system_host_keys()
        s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            s.connect(host,22,user,passwd,timeout=5)
            stdin,stdout,stderr = s.exec_command(cmd)
    
            cmd_result = stdout.read(),stderr.read()
            print msg
            for line in cmd_result:
                    print line,
    
            s.close()
        except paramiko.AuthenticationException:
            print msg
            print 'AuthenticationException Failed'
        except paramiko.BadHostKeyException:
            print msg
            print "Bad host key"
    
    p = multiprocessing.Pool(processes=20)
    #----------------等他与上面那一句
    #from multiprocessing import Process,Pool
    #p = Pool(20)
    #----------------
    cmd=raw_input('CMD:')
    f=open('serverlist.conf')#当前目录下建立该配置文件,格式按照如下的方式
    list = f.readlines()
    f.close()
    for IP in list:
        host=IP.split()[0]
        port=int(IP.split()[1])
        user=IP.split()[2]
        passwd=IP.split()[3]
        p.apply_async(ssh_cmd,(host,port,user,passwd,cmd))#多进程执行的一个方法。
    
    p.close()
    p.join()

    进程池

    进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,

    如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

    进程池中有两个方法及demo:

    • apply
    • apply_async
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from  multiprocessing import Process,Pool
    import time
      
    def Foo(i):
        time.sleep(2)
        return i+100
      
    def Bar(arg):
        print arg
      
    pool = Pool(5)
    #print pool.apply(Foo,(1,))
    #print pool.apply_async(func =Foo, args=(1,)).get()
      
    for i in range(10):
        pool.apply_async(func=Foo, args=(i,),callback=Bar)
      
    print 'end'
    pool.close()
    pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
    View Code

    多进程之间,也可以数据共享,同时数据共享时,产生脏数据时,也可以用锁进行锁定,防止脏数据。

    这个平时没用到过,有碰到时,再度娘吧。

    协程:(这个平时也没用到过,先标注下概念,以后有用到再加深吧)

    线程和进程都是系统帮咱们开辟的。
    对于协程来说,是程序员操控的。

    协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。

            协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。

    适用场景:其实在其他语言中,协程的其实是意义不大的多线程即可已解决I/O的问题,但是在python因为他有GIL(Global Interpreter Lock 全局解释器锁 )在同一时间只有一个线程在工作,所以:如果一个线程里面I/O操作特别多,协程就比较适用

    demo的话,自己整特明白了再说。

    关于更多请参考:http://www.cnblogs.com/wupeiqi/articles/4839959.html(写的很不错)

  • 相关阅读:
    Linux下c程序的编译方法:
    Linux分区机制和常见命令
    java虚拟机内存大小调整:
    break、continue、return循环三剑客之异同
    Scanner中的nextInt()陷阱
    windbg无法下载符号文件
    各种函数调用约定及浮点数传参
    一个crackme的分析
    SetProcessAffinityMask的问题
    x64内联汇编注意点
  • 原文地址:https://www.cnblogs.com/shoug/p/5137360.html
Copyright © 2020-2023  润新知