zoukankan      html  css  js  c++  java
  • 线程

    线程与进程的关系

      1,一个进程至少会有一个进程

      2,线程是不能独立存在的

    线程与进程的区别

      1,进程是计算机的最小资源分配单位

      2,线程是cpu的最小调度单位

      3,进程之间的数据是隔离的

      4,同一个进程内的的线程直接的数据是共享的

    GIL锁,全局解释器锁,全局锁

      cpython才会有

      同一个进程内在同一个时刻只有有个线程会被CPU调度

    在多I/O阻塞的程序中,用多线程

    在高计算的程序中,用多进程

    线程直接的数据是共享的

     1 from threading import Thread
     2 import time
     3 n=100
     4 def func():
     5     global n
     6     n=n-1
     7 t=Thread(target=func).start()
     8 time.sleep(1)
     9 print(n)    
    10     #99
    View Code

    守护线程

    守护线程与守护进程

      守护进程  守护进程会随主进程代码的结束而结束(程序的报活)

      守护线程  主线程在结束之后,会等待子线程的结束而结束

      主线程的结束,就意味着主进程的结束

     1 from threading import Thread
     2 def func():
     3     print("守护线程")
     4 def func1():
     5     print("子线程")
     6 t=Thread(target=func)
     7 t1=Thread(target=func1)
     8 t.daemon=True
     9 t.start()
    10 t1.start()
    11 print("主进程")
    12 守护线程
    13 子线程
    14 主进程
    View Code

    互斥锁与递归锁

    为什么线程中有GIL锁,还要有锁?

      当在进行 +=,-= 的时候,会数据不安全(要进行取值,计算,赋值三步操作,有可能在做完取值,计算之后就时间片轮转,这时候就没办法赋值,另外的

      的线程就继续取值)

      列表的append,pop操作,队列,logging模块的数据是安全的

    递归锁   

      当一个线程在得到一把锁之后,还需要得到另一把锁

      一个线程的到了一把锁,另一把锁被另外一个线程的到了,就会发生死锁

      递归锁是解决死锁最快的方法,但不是最好的方法,还是要慢慢换用互斥锁

      出现死锁不是互斥锁的原因,而是程序员编码时的逻辑问题

    信号量      

      信号量是计数器和锁来实现的

     1 from threading import Thread,Semaphore
     2 import time
     3 def func(s):
     4     s.acquire()
     5     time.sleep(1)
     6     print("hello")
     7     s.release()
     8 s=Semaphore(3)
     9 for i in range(10):
    10     t=Thread(target=func,args=(s,)).start()
    View Code

    事件

    e=Event()

    e.wait()  如果e.is_set==False将阻塞线程

    e.set()  设置event的值为True

    e.clear  恢复event的值为False

    e.is_set()  返回event的状态值

     1 from threading import Thread,Event
     2 import time
     3 def check(e):
     4     print("开始检测数据库连接")
     5     time.sleep(2)
     6     e.set()
     7 def connect(e):
     8     time.sleep(1)
     9     for i in range(3):
    10         e.wait(1)
    11         if e.is_set():
    12             print("数据库连接成功")
    13             break
    14         else:print('第{}次数据库连接失败'.format(i+1))
    15 e=Event()
    16 t=Thread(target=connect,args=(e,)).start()
    17 t1=Thread(target=check,args=(e,)).start()
    View Code

    条件

    wait()

    notify()

    wait和notify必须在acquire和release中间使用

     1 eading import Thread,Condition
     2 def func(con,name):
     3     print("{}等待中".format(name))
     4     con.acquire()
     5     con.wait()
     6     print("{}在游戏中".format(name))
     7     con.release()
     8 con=Condition()
     9 for i in range(20):
    10     t=Thread(target=func,args=(con,i))
    11     t.start()
    12 con.acquire()
    13 con.notify(3)
    14 con.release()
    View Code

    定时器

    1 from threading import Timer
    2 def func():
    3     print("666")
    4 t=Timer(3,func).start()
    View Code

    队列

    Queue  先进先出

    LifoQueue  栈,后进先出

    PriorityQueue  优先级队列

      

  • 相关阅读:
    SVN服务器搭建和使用
    oracle 存储过程
    PLSQL函数
    PL/SQL --> 游标
    PL SQL 游标学习
    PLSQL存储过程
    利用jqueryRotare实现抽奖转盘
    NSString 与NSMutableString的区别
    第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法
    第8章 应用协议 图解TCP/IP 详解
  • 原文地址:https://www.cnblogs.com/ruoxiruoxi/p/9700924.html
Copyright © 2011-2022 走看看