zoukankan      html  css  js  c++  java
  • 线程,进程概念

    当多个客户端访问服务端的时候,每个客户端都会对服务端说:’嗨,我想连接你‘。服务端的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(写的很不错)

  • 相关阅读:
    LintCode "Maximum Gap"
    LintCode "Wood Cut"
    LintCode "Expression Evaluation"
    LintCode "Find Peak Element II"
    LintCode "Remove Node in Binary Search Tree"
    LintCode "Delete Digits"
    LintCode "Binary Representation"
    LeetCode "Game of Life"
    LintCode "Coins in a Line"
    LintCode "Word Break"
  • 原文地址:https://www.cnblogs.com/shoug/p/5137360.html
Copyright © 2011-2022 走看看