进程与线程(05-15)

---恢复内容开始---

1.线程(thread)

        所有的指令都是有CPU控制的,执行的,运算的。

       线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪阻塞运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
 
       线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指令运行时的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。(来源:https://baike.baidu.com/item/%E7%BA%BF%E7%A8%8B)
    
2.进程(process)
       
        狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。
        广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
    
       注: 进程要操作CPU,必须要先创建一个线程,一个进程中可以包含多个线程,所有在同一个进程里的线程是共享同一块内存的。
        

         An executing instance of a program is called a process.

               Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, (环境变量)environment variables, a priority class(优先级), minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.

 
3.  进程与线程的区别:
        问题①:启动一个进程快还是一个启动一个线程快?
        回答:启动线程快。
    
         问题②: 进程和线程哪个快?
         回答:没有可比性。
       
         区别:① 线程共享内存空间,进程的内存是独立的;
                   ② 进程的线程之间可以直接交流;两个进程之间交流,必须通过中间代理来实现。
                   ③ 创建新的线程很简单,创建新进程需要对其父进程进行一次克隆。
                   ④ 一个线程可以控制和操作同一个进程里的其他线程,但是进程只能操作子进程;
                   ⑤ 修改主线程可能会影响子线程,修改父进程不会影响子进程。
 
4. 实例
        
 1 import threading
 2 import time
 3 def run(n):
 4     print("task", n)
 5     time.sleep(2)
 6 
 7 t1 = threading.Thread(target=run,args=("t1",))
 8 t2 = threading.Thread(target=run,args=("t2",))
 9 
10 t1.start()
11 t2.start()
12 
13 #run("t1")   #t1.join()   等待t1 进程完成
14 #run("t2")

5. 多线程案例

 1 import threading
 2 
 3 class MyThread(threading.Thread):
 4     def __init__(self,n):
 5         super(MyThread,self).__init__()
 6         self.n = n
 7 
 8     def run(self):
 9         print("runnint task", self.n)
10 
11 
12 t1 = MyThread("t1")
13 t2 = MyThread("t2")
14 
15 t1.start()
16 t2.start()

6. 主线程与子线程

 1 import threading
 2 import time
 3 def run(n):
 4     print("task", n, threading.current_thread(), threading.active_count())  #查看当前线程是子线程还是主线程
 5     time.sleep(2)
 6 
 7 start_time = time.time()
 8 t_objs = []   #列表,存线程实例
 9 for i in range(50):
10     t = threading.Thread(target=run,args=("t-%s" %i ,))   #注意逗号不能丢
11     t.start()
12     t_objs.append(t)
13 
14 for t in t_objs:
15     t.join()    #等待所有的子进程结束
16 
17 print("----------all threads has finished..", threading.current_thread(), threading.active_count())#活动线程的个数
18 print("cost:", time.time()-start_time)    #计算整个进程的时间

7.  守护线程

不管子线程是否结束,主线程运行完程序就退出了

import threading
import time
def run(n):
    print("task", n, threading.current_thread(), threading.active_count())  #查看当前线程是子线程还是主线程
    time.sleep(2)

start_time = time.time()
t_objs = []   #列表,存线程实例
for i in range(50):
    t = threading.Thread(target=run,args=("t-%s" %i ,))   #注意逗号不能丢
    t.setDaemon(True)  #把当前线程设置为守护线程,(相当于仆人了,不管了)
    t.start()
    t_objs.append(t)

for t in t_objs:
    t.join()    #等待所有的子进程结束

print("----------all threads has finished..", threading.current_thread(), threading.active_count())#活动线程的个数
print("cost:", time.time()-start_time)    #计算整个进程的时间

 8.  线程锁(也称互斥锁Mutex)之 GIL  vs Lock

图片来源:https://www.cnblogs.com/alex3714/articles/5230609.html

8.1  递归锁

RLock  与 Lock

9. 线程锁之信号量(Semaphore)

10.线程之 Events (事件)

红绿灯的实例: 设置全局变量控制红绿灯色切换。 

     标志位的设定

方法:event.set()

          event.clear()

          event.wait()

          event.is_set()

11.队列(queue)

注:python2.x中为import Queue;  python3.x 中都为小写queue。

 ①定义:一个有顺序的容器,

②作用:a.解耦:

              b.提高运行效率;

③队列与列表:

         都有顺序;列表取出一个数据相当于复制一份,原列表中依然存在着个数据;对列中拿走一个数据,就从队列中消失了。

④ 方法:

     queue.Queue()  生成一个队列;先进后出

     queue.Queue(maxsize=num)  生成一个队列,并限制大小

     put("xxx")  往队列中放数据;

     put(3)  放入整数;

      qsize()   查看队列大小;

      get()  取队列中的数据,(无参数,因为先入先出),最后一个取出来,再取会卡住,

                     可用get_nowait(),会抛出异常;

                      or get(block = False)   同上,也会抛出异常;

                      or get(timeout = 1)   ,卡一秒后抛出异常;

       queue.LifoQueue()  #last in first out  #后进先出

       queue.PriorityQueue  #存储数据是可设置优先级的队列,(VIP数据

       task_done()  

12. 生产者消费者模型

 1 import queue
 2 import threading
 3 import time
 4 
 5 q = queue.Queue(maxsize=10)
 6 
 7 def Producer (name):
 8     count = 1
 9     while True:
10         q.put("骨头%s" %count)
11         print("生产了骨头" ,count)
12         count += 1
13         time.sleep(0.3)
14 
15 
16 def Consumer(name):
17     #while q.qsize() > 0:
18     while True:
19         print("[%s] 取到[%s] 并吃了它。。。" %(name, q.get()))
20         time.sleep(1)
21 
22 p = threading.Thread(target=Producer, args=("xiaolaizi",))
23 c = threading.Thread(target=Consumer, args=("大黄狗",))
24 c1 = threading.Thread(target=Consumer, args=("小奶狗",))
25 p.start()
26 c.start()
27 c1.start()

       

      

      

     

   

---恢复内容结束---

原文地址:https://www.cnblogs.com/bltstop/p/10123012.html