zoukankan      html  css  js  c++  java
  • 进程之间的相互通信、生产者消费者模型、线程以及创建方式、线程对象以及常用的方法、守护线程、

    有关于人工智能一些高端功能的网站:

    1、百度api

    http://ai.baidu.com/?track=cp:ainsem|pf:pc|pp:tongyong-pinpai|pu:pinpai-baiduAI|ci:|kw:10003812

    2、科大讯飞(语音方面很专业)

    https://www.xfyun.cn/?ch=bdtg&renqun_youhua=646957

    3、图灵机器人

    http://www.turingapi.com/

    进程之间的相互通信:

    队列:先进先出

    堆栈:先进后出

    代码理解队列:

     1 from multiprocessing import Queue
     2 q = Queue(5)  # 括号内可以传参数 表示的是这个队列的最大存储数
     3 # 往队列中添加数据
     4 q.put(1)
     5 q.put(2)
     6 # print(q.full())  # 判断队列是否满了
     7 q.put(3)
     8 q.put(4)
     9 q.put(5)
    10 # print(q.full())
    11 # q.put(6)  # 当队列满了之后 再放入数据 不会报错 会原地等待 直到队列中有数据被取走(阻塞态)
    12 print(q.get())
    13 print(q.get())
    14 print(q.get())
    15 print(q.empty())  # 判断队列中的数据是否取完
    16 print(q.get())
    17 print(q.get())
    18 print(q.empty())
    19 # print(q.get_nowait())  # 取值 没有值不等待直接报错
    20 # print(q.get())  # 当队列中的数据被取完之后 再次获取 程序会阻塞 直到有人往队列中放入值
    21 """
    22 full
    23 get_nowait
    24 empty
    25 都不适用于多进程的情况
    26 """
    View Code

    进程间通信的ipc机制:

     1 from multiprocessing import Process,Queue
     2 
     3 def producer(q):
     4     q.put('hello GF~')
     5 
     6 def consumer(q):
     7     print(q.get())
     8 
     9 if __name__ == '__main__':
    10     q = Queue()
    11     p = Process(target=producer,args=(q,))
    12     c = Process(target=consumer, args=(q,))
    13     p.start()
    14     c.start()
    15 
    16 
    17 """
    18 子进程放数据 主进程获取数据
    19 两个子进程相互放 取数据
    20 """
    View Code

    生产者消费者模型:

     1 """
     2 生产者:生产/制造数据的
     3 消费者:消费/处理数据的
     4 例子:做包子的,买包子的
     5         1.做包子远比买包子的多
     6         2.做包子的远比包子的少
     7         供需不平衡的问题
     8 """
     9 from multiprocessing import Process,Queue,JoinableQueue
    10 import random
    11 import time
    12 
    13 
    14 def producer(name,food,q):
    15     for i in range(10):
    16         data = '%s生产了%s%s'%(name,food,i)
    17         time.sleep(random.random())
    18         q.put(data)
    19         print(data)
    20 
    21 def consumer(name,q):
    22     while True:
    23         data = q.get()
    24         if data == None:break
    25         print('%s吃了%s'%(name,data))
    26         time.sleep(random.random())
    27         q.task_done()  # 告诉队列你已经从队列中取出了一个数据 并且处理完毕了
    28 
    29 
    30 
    31 if __name__ == '__main__':
    32     q = JoinableQueue()
    33     p = Process(target=producer,args=('大厨egon','馒头',q))
    34     p1 = Process(target=producer,args=('跟班tank','生蚝',q))
    35     c = Process(target=consumer,args=('许兆龙',q))
    36     c1 = Process(target=consumer,args=('吃货jerry',q))
    37     p.start()
    38     p1.start()
    39     c.daemon = True
    40     c1.daemon = True
    41     c.start()
    42     c1.start()
    43     p.join()
    44     p1.join()
    45 
    46     q.join()  # 等到队列中数据全部取出
    47     # q.put(None)
    48     # q.put(None)
    View Code

    线程:

    什么是线程

        进程线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物
    进程:资源单位
    线程:执行单位
    将内存比如成工厂
    那么进程就相当于是工厂里面的车间
    而你的线程就相当于是车间里面的流水线
    ps:每个进程都自带一个线程,线程才是真正的执行单位,进程只是在线程运行过程中
    提供代码运行所需要的资源
    为什么要有线程
    开进程
    1.申请内存空间 耗资源
    2."拷贝代码" 耗资源
    一个进程内可以起多个线程,并且线程与线程之间数据是共享的
    ps:开启线程的开销要远远小于开启进程的开销

    线程的两种创建方式:

    方式一:

     1 # from threading import Thread
     2 # import time
     3 #
     4 # def task(name):
     5 #     print('%s is running'%name)
     6 #     time.sleep(3)
     7 #     print('%s is over'%name)
     8 # # 开线程不需要在__main__代码块内 但是习惯性的还是写在__main__代码块内
     9 # t = Thread(target=task,args=('egon',))
    10 # t.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
    11 # # 小的代码执行完 线程就已经开启了
    12 # print('主')
    View Code

    方式二:

     1 from threading import Thread
     2 import time
     3 
     4 class MyThread(Thread):
     5     def __init__(self,name):
     6         super().__init__()
     7         self.name = name
     8 
     9     def run(self):
    10         print('%s is running'%self.name)
    11         time.sleep(3)
    12         print('%s is over'%self.name)
    13 
    14 t = MyThread('egon')
    15 t.start()
    16 print('')
    View Code

    线程对象以及常用的方法:

     1 from threading import Thread,current_thread,active_count
     2 import time
     3 import os
     4 
     5 def task(name,i):
     6     print('%s is running'%name)
     7     print('子current_thread:', current_thread().name)
     8     print('',os.getpid())
     9     time.sleep(i)
    10 
    11     print('%s is over'%name)
    12 # 开线程不需要在__main__代码块内 但是习惯性的还是写在__main__代码块内
    13 t = Thread(target=task,args=('egon',1))
    14 t1 = Thread(target=task,args=('jason',2))
    15 t.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
    16 t1.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
    17 t1.join()  # 主线程等待子线程运行完毕再执行
    18 #因为这个代码需要等t1运行完毕才执行,所以当在等t1执行结束的过程中t也运行结束所以活跃数为1
    19 print('当前正在活跃的线程数',active_count())
    20 # 小的代码执行完 线程就已经开启了,所以不是先打印主
    21 print('')
    22 print('主current_thread:',current_thread().name)
    23 print('',os.getpid())
    View Code

    守护线程:

    即当主线程结束时,设置的守护子线程也会结束。

    daemon:需要设置在start之前。

    守护进程的小例子:加深理解!

     1 from threading import Thread
     2 from multiprocessing import Process
     3 import time
     4 
     5 
     6 def foo():
     7     print(123)
     8     time.sleep(1)
     9     print("end123")
    10 
    11 
    12 def bar():
    13     print(456)
    14     time.sleep(3)
    15     print("end456")
    16 
    17 
    18 """
    19 因为主线程需要等待其他非守护线程结束才能结束,
    20 所以当t1被设置为守护线程之后,
    21 理论上当主线程打印完毕后就结束了运行了,不会运行sleep后的代码了
    22 但是这个时候t2(非守护线程)的运行并没有结束,所以主线程也不会结束
    23 所以线程t1也继续运行。
    24 """
    25 
    26 if __name__ == '__main__':
    27     t1 = Thread(target=foo)
    28     t2 = Thread(target=bar)
    29     t1.daemon = True
    30     t1.start()
    31     t2.start()
    32     print("main-------")
    View Code
     1 from threading import Thread,current_thread
     2 import time
     3 
     4 
     5 def task(i):
     6     print(current_thread().name)
     7     time.sleep(i)
     8     print('GG')
     9 
    10 
    11 for i in range(3):
    12     t = Thread(target=task,args=(i,))
    13     # 设置为守护线程后,主线程结束,子线程立马结束。
    14     t.daemon = True
    15     t.start()
    16 print('')
    17 
    18 # t = Thread(target=task,args=(1,))
    19 # t.daemon = True
    20 # t.start()
    21 # print('主')
    22 # 主线程运行结束之后需要等待子线程结束才能结束呢?
    23 """
    24 主线程的结束也就意味着进程的结束
    25 主线程必须等待其他非守护线程的结束才能结束
    26 (意味子线程在运行的时候需要使用进程中的资源,而主线程一旦结束了资源也就销毁了)
    27 """
    View Code

    线程之间的数据是共享的:

    验证代码:

    1 from threading import Thread
    2 money = 666
    3 def task():
    4     global money
    5     money = 999
    6 t = Thread(target=task)
    7 t.start()
    8 t.join()
    9 print(money)
    View Code

    互斥锁:

     1 from threading import Thread,Lock
     2 import time
     3 """
     4 在不设置互斥锁时,100个线程同时运行,
     5 每个线程得到的数字n都是100,都进行减一,所以结果为99
     6 当多个线/进程去处理一个数据时会发生错乱时,需要加锁
     7 设置互斥锁之后,锁只需要加在处理数据的部分,100个线程之间进行抢锁,
     8 使并发变成了串行,降低了效率,提高了数据的安全性。所以结果变为了0
     9 """
    10 
    11 n = 100
    12 
    13 def task(mutex):
    14     global  n
    15     mutex.acquire()
    16     tmp = n
    17     time.sleep(0.1)
    18     n = tmp - 1
    19     mutex.release()
    20 
    21 t_list = []
    22 mutex = Lock()
    23 for i in range(100):
    24     t = Thread(target=task,args=(mutex,))
    25     t.start()
    26     t_list.append(t)
    27 for t in t_list:
    28     t.join()
    29 print(n)
    View Code









  • 相关阅读:
    python类的继承
    Numpy float64和Python float是一样的
    ndarray的用法总结
    pandas的Panel类型dtype
    C++中类的前向声明
    numpy的searchsorted细品
    发现Boost官方文档的一处错误(numpy的ndarray)
    C++读取dll文件所在目录
    64位的pyd报"ImportError: No module named"错误
    WIN32,_WIN32_WIN64
  • 原文地址:https://www.cnblogs.com/yangjiaoshou/p/11340924.html
Copyright © 2011-2022 走看看