• 【Python】多线程-2


    1、    进程和线程的区别:

    (1) 一个进程可以有多个线程,一个进程中的多个线程共享该进程的所有资源,多线程切换比多进程切换快,因为不用上下文切换,Python中并发建议用多进程

    (2) 进程是资源分配的最小单位,线程是程序执行的最小单位

    (3) 进程有自己的独立地址空间,而线程是共享进程中的数据

    2、    并行和并发:并行指在某一秒,并发指在某一时间段

    3、    Pip list 查看各API版本号

    4、    守护线程:比如主线程A中创建了子线程B,并且在主线程A中调用了B.setDeamon(),意思是,把B设置为守护线程,这时候,要是主线程A执行结束了,就不管子线程B是否完成,一并和主线程A退出。这就是 setDaemon方法的含义, 这基本和 join是相反的。此外,还有个要特别注意必须在 start()方法调用之前调用此方法,如果不设置为守护线程程序有可能会被无线挂起

    5、    线程创建的方法:

    (1) threading.Thread创建

    (2) 通过继承Thread类创建线程 : class MyThread(threading.Thread)

    6、    线程拥有的方法:

    (1) isAlive() 返回线程是否在运行。运行指启动后,结束前。

    (2) getName() 获取线程名字

    (3) setName() 设置线程名字

    (4) isDeamon() 判断线程是否随主线程一起结束

    (5) setDeamon() 设置是否为守护线程

    (6) start() 启动线程

    (7) join() 等待所有子线程执行完后才能接着往下执行

    (8) run() 用于表示线程活动的方法,通常需要重写

    (9) pool.map()

    7、    并发线程的两种关系:同步与互斥

    (1) 锁可以实现线程间的互斥

    (2) 生产者和消费者是线程同步的例子

    8、    线程加锁:threading.Semaphore()

    #练习:守护进程
    import multiprocessing
    import time, logging
    import sys
    
    def daemon():
      p = multiprocessing.current_process()
      print 'Starting:', p.name, p.pid
      sys.stdout.flush() # 将缓冲区数据写入终端
      # time.sleep(2)
      print 'Exiting :', p.name, p.pid
      sys.stdout.flush()
    
    def non_daemon():
      p = multiprocessing.current_process()
      print 'non_Starting:', p.name, p.pid
      sys.stdout.flush()
      print 'non_Exiting :', p.name, p.pid
      sys.stdout.flush()
    
    if __name__ == '__main__':
      # 设置日志输出到控制台
      multiprocessing.log_to_stderr()
      logger = multiprocessing.get_logger()
      # 设置输出日志的级别
      logger.setLevel(logging.DEBUG)
    
      d = multiprocessing.Process(name='daemon', target=daemon)
      d.daemon = True
      n = multiprocessing.Process(name='non-daemon', target=non_daemon)
      n.daemon = False
      d.start()
      time.sleep(1)
      n.start()
      # d.join(1)
      # n.join()
      print 'd.is_alive()', d.is_alive()
      print "n.is_alive()", n.is_alive()
      print "main Process end!"
    
    
    
    #练习:线程池
    
    import time
    from multiprocessing.dummy import Pool as ThreadPool
    #ThreadPool表示给线程池取一个别名ThreadPool
    
    def run(fn):
        time.sleep(2)
        print fn
    
    if __name__ == "__main__":
        testFL = [1,2,3,4,5]
        #创建10个容量的线程池并发执行
        pool = ThreadPool(10)
        pool.map(run,testFL)
        pool.close()
        pool.join()
    
    
    
    #练习:锁可以实现线程间的互斥
    import threading
    import time
    
    data = 0
    lock = threading.Lock()#创建一个锁对象
    
    def func() :
      global data
      print "%s acquire lock...
    " %threading.currentThread().getName()
      if lock.acquire : #if 1:改成这个耗时会长
        print "%s get lock...
    " %threading.currentThread().getName()
        for i in range(100000):
            data += 1 #must lock
        #time.sleep(2)#其它操作
        print "%s release lock...
    " %threading.currentThread().getName()
    
        #调用release()将释放锁
        #lock.release()
    
    startTime = time.time()
    t1 = threading.Thread(target = func)
    t2 = threading.Thread(target = func)
    t3 = threading.Thread(target = func)
    t1.start()
    t2.start()
    t3.start()
    t1.join()
    t2.join()
    t3.join()
    print data
    
    endTime = time.time()
    print "used time is", endTime - startTime
    
    #练习:线程同步
    from Queue import Queue #队列类
    import random    
    import threading    
    import time      
    
    #生成者线程
    class Producer(threading.Thread):    
        def __init__(self, t_name, queue): 
            #调用父线程的构造方法。
            threading.Thread.__init__(self, name = t_name)    
            self.data = queue  
    
        def run(self):    
            for i in range(5):    
                print "%s: %s is producing %d to the queue!
    " %(time.ctime(), self.getName(), i)  
                self.data.put(i)#向队列中添加数据
                #产生一个0-2之间的随机数进行睡眠
                time.sleep(random.randrange(10) / 5)    
            print "%s: %s finished!" %(time.ctime(), self.getName()) 
    #消费者线程
    class Consumer(threading.Thread):    
        def __init__(self, t_name, queue):    
            threading.Thread.__init__(self, name = t_name)  
            self.data = queue  
    
        def run(self):    
            for i in range(5):    
                val = self.data.get()#从队列中取出数据
                print "%s: %s is consuming. %d in the queue is consumed!
    " %(time.ctime(), 
    
    self.getName(), val)
                time.sleep(random.randrange(10))  
            print "%s: %s finished!" %(time.ctime(), self.getName()) 
    
    #Main thread    
    def main():    
        queue = Queue()#创建一个队列对象(特点先进先出)
        producer = Producer('Pro.', queue)#生产者对象
        consumer = Consumer('Con.', queue)#消费者对象
        producer.start()    
        consumer.start()  
        producer.join()    
        consumer.join()  
        print 'All threads terminate!'  
    
    if __name__ == '__main__':  
        main()
    
    
    #练习:线程锁
    from threading import Thread, Lock
    import threading
    
    def run(lock, num):  
      lock.acquire() # 获得锁
      # 取得当前线程的线程名
      threadName = threading.current_thread().getName()
      print "%s, Hello Num: %s" %(threadName, num)  
      lock.release() # 释放锁
    
    if __name__ == '__main__':  
        lock = Lock()  # 创建一个共享锁实例
        for num in range(20):  
          Thread(name = 'Thread-%s' %str(num), target = run, args = (lock, num)).start()
    
    
    #练习:多把线程锁
    from threading import Thread,Lock
    import threading
    import time
    
    def worker(s,i):
        s.acquire()
        print(threading.current_thread().name + " acquire")
        time.sleep(i)
        print(threading.current_thread().name + " release")
        s.release()
    
    if __name__=="__main__":
        s=threading.Semaphore(3)
        for i in range(5):
            t=Thread(target=worker,args=(s,i*2))
            t.start()
            #t.join #这里加了join就会逐个执行了
  • 相关阅读:
    Three.js入门和搭建HelloWorld
    CentOS中使用Docker来部署Tomcat
    CentOS中使用Docker来部署Nginx
    Windows中通过bat定时执行命令和mysqldump实现数据库备份
    Geoserver在Linux上的安装(图文教程)
    Linux上怎样停止服务(jar包)、查看进程路径、关闭指定端口
    Java中怎样监测局域网内ip是否互通,类似ping
    Android和JS之间互相调用方法并传递参数
    Android中使用WebView加载本地html并支持运行JS代码和支持缩放
    ARC072C
  • 原文地址:https://www.cnblogs.com/jingsheng99/p/8850350.html
Copyright © 2020-2023  润新知