0701-协程

聊天室

server

from multiprocessing import Pool, cpu_count,Manager # 导入进程的manager对象
from multiprocessing.pool import ThreadPool
import socket


# 从队列中拿出数据,发给所有连接上的客户端
def send_data(dict_proxy, queue_proxy):
    while True:
        data = queue_proxy.get()  # 从队列中拿出消息,发送给所有连接上来的客户端
        print(data.decode())
        for conn in dict_proxy.values():  # 去字典里拿对等连接套接字
            conn.send(data)


# 处理客户端发来的信息
def worker_thread(connection, addr, dict_proxy, queue_proxy):
    while True:
        try:
            recv_data = connection.recv(1024)
            if recv_data:
                data = "来自{addr} 的消息:{data}".format(addr=addr, data=recv_data.decode())
                queue_proxy.put(data.encode())  # 把消息添加到到队列中
            else:
                raise Exception
        except:
            dict_proxy.pop(addr)  # 从字典中删掉退出的客户端
            data = '用户{}退出'.format(addr)
            queue_proxy.put(data.encode())  # 把退出消息添加到队列中
            connection.close()
            break


# 处理 客户端建立连接  给客户端发送消息 客户端发来消息
def worker_process(server, dict_proxy, queue_proxy):
    thread_pool = ThreadPool(cpu_count() * 2)  # 通常分配2倍CPU个数的线程
    # 把 向所有人发布客户端消息send_data 丢进进程池thread_pool
    thread_pool.apply_async(send_data, args=(dict_proxy, queue_proxy))

    while True:
        conncetion, remote_address = server.accept()  # 生成对等套接字

        dict_proxy[remote_address] = conncetion  # 把对等套接字加入字典中 保存起来
        # dict_proxy.setdafault(remote_address,conncetion)

        data = '用户{}登录'.format(remote_address)
        queue_proxy.put(data.encode())  # 将用户登录消息添加到队列中

        # 把 处理客户端消息worker_thread 丢进进程池thread_pool
        thread_pool.apply_async(worker_thread, args=(conncetion, remote_address, dict_proxy, queue_proxy))


if __name__ == '__main__':

    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(1000)

    mgr = Manager()
    dict_proxy = mgr.dict()  # 用来保存连接上来的客户端,对等连接套接字   字典(哈希结构)对于数据的查找速度快
    queue_proxy = mgr.Queue()  # 把客户端发过来的消息通过队列传递  进程安全队列操作 mgr.Queue

    n = cpu_count()  # 打印当前电脑的cpu核数
    process_pool = Pool(n)
    for i in range(n):  # 充分利用CPU,为每一个CPU分配一个进程
        process_pool.apply_async(worker_process, args=(server, dict_proxy, queue_proxy))  # 把server丢到两个进程里面

    process_pool.close()
    process_pool.join()

client

import socket
import threading


def recv_data():
   while True:
      data = client.recv(1024)
      print(data.decode())


client = socket.socket()
client.connect(('127.0.0.1', 8080))

# 开一个线程处理服务端随时发来的信息
thread = threading.Thread(target=recv_data, daemon=True)
thread.start()

# 接受输入
while True:
   a = input('')
   client.send(a.encode())
ssh://pyvip@127.0.0.1:1234/home/pyvip/.virtualenvs/py3env/bin/python3 -u /home/pyvip/py_case/server1.py
用户('127.0.0.1', 37576)连接
用户('127.0.0.1', 37578)连接
用户('127.0.0.1', 37580)连接
来自('127.0.0.1', 37580) 的消息:1
ssh://pyvip@127.0.0.1:1234/home/pyvip/.virtualenvs/py3env/bin/python3 -u /home/pyvip/py_case/client1.py
用户('127.0.0.1', 37576)连接
用户('127.0.0.1', 37578)连接
用户('127.0.0.1', 37580)连接
来自('127.0.0.1', 37580) 的消息:1
ssh://pyvip@127.0.0.1:1234/home/pyvip/.virtualenvs/py3env/bin/python3 -u /home/pyvip/py_case/client1.py
用户('127.0.0.1', 37578)连接
用户('127.0.0.1', 37580)连接
来自('127.0.0.1', 37580) 的消息:1
ssh://pyvip@127.0.0.1:1234/home/pyvip/.virtualenvs/py3env/bin/python3 -u /home/pyvip/py_case/client1.py
用户('127.0.0.1', 37580)连接
1
1
来自('127.0.0.1', 37580) 的消息:1

协程

yield

yield对象 返回这个对象 暂停这个函数 等待下次next重新激活

def fun():
    yield 1     # 返回1 暂停函数
    print('第一次执行')
    yield 2     # 返回2 暂停函数
    print('第二次执行')


a = fun()
print(a)  # 生成器对象 但没有被执行
b = next(a)  # next()调用 执行函数fun() 执行到yield时 暂停 并返回 1
print(b)  # 输出1
<generator object fun at 0xb719883c>
1
def fun():
    yield 1     # 返回1 暂停函数
    print('第一次执行')
    yield 2     # 返回2 暂停函数
    print('第二次执行')


a = fun()
print(a)  # 生成器对象 但没有被执行
b = next(a)  # next()调用 执行函数fun() 执行到yield时 暂停 并返回 1
print(b)  # 输出1
b = next(a)  # 从上一次停止的地方继续执行 输出  第一次执行   并返回2
<generator object fun at 0xb726389c>
1
第一次执行
def fun():
    yield 1     # 返回1 暂停函数
    print('第一次执行')
    yield 2     # 返回2 暂停函数
    print('第二次执行')


a = fun()
print(a)  # 生成器对象 但没有被执行
b = next(a)  # next()调用 执行函数fun() 执行到yield时 暂停 并返回 1
print(b)  # 输出1
b = next(a)  # 从上一次停止的地方继续执行 输出  第一次执行   并返回2
print(b) # 输出2
<generator object fun at 0xb718989c>
1
第一次执行
2
def fun():
   result = yield 1
   print('result:',result)
   print('第一次执行')
   yield 2
   print('第二次执行')


a = fun()
b = next(a)
print(b)
1
def fun():
   result = yield 1
   print('result:',result)
   print('第一次执行')
   yield 2
   print('第二次执行')


a = fun()
b = next(a)
print(b)
next(a)
1
result: None
第一次执行

send 一个对象 激活生成器 执行生成器里面的代码 遇到yield回到调用位置

def fun():
   result = yield 1
   print('result:',result)
   print('第一次执行')
   yield 2
   print('第二次执行')


a = fun()
b = next(a)
print(b)
# next(a)
a.send('你好')    # 可以传值
1
result: 你好
第一次执行

next(a) 相当于 a.send(None)

def fun():
   result = yield 1
   print('result:',result)
   print('第一次执行')
   yield 2
   print('第二次执行')


a = fun()
b = next(a)  # 第一次
print(b)
next(a)     # 第二次 
a.send('你好')  # 第三次 抛出StopIteration的异常 因后面没代码了
1
result: None
第一次执行
第二次执行
Traceback (most recent call last):
  File "/home/pyvip/py_case/进阶/并发/协程/yield_test.py", line 13, in <module>
    a.send('你好')
StopIteration
def fun():
   while True:
      result = yield 1
      print('result:',result)
      print('第一次执行')
      yield 2
      print('第二次执行')


a = fun()
b = next(a)
print(b)
next(a)
a.send('你好')
1
result: None
第一次执行
第二次执行
def fun():
   i = 1
   while True:
      print(122)
      print(i)
      x = yield i
      i = i + 1
      print('第%d次执行fun函数:' % i)
      print('x的值:', x)


a = fun()
next(a)
a.send('hello')
print('-' * 10)
a.send('python')
122
1
第2次执行fun函数:
x的值: hello
122
2
----------
第3次执行fun函数:
x的值: python
122
3
def fun():
    i = 1
    while True:
        x = yield i
        i = i + 1
        print('第%d次执行fun函数:' % i)
        print('x的值:', x)


a = fun()
next(a)
a.send('hello')
print('-' * 10)
a.send('python')
第2次执行fun函数:
x的值: hello
----------
第3次执行fun函数:
x的值: python

-

生产者 消费者模型

import random
import time


def produce(consum):  # 生产者
   next(consum)
   while True:
      item = random.randint(0, 99)  # 随机产生一个0-99之间的数
      print('生产者生产了', item)
      consum.send(item)  # 把item给消费者 切换到consumer()运行
      time.sleep(1)  # 每生产一个就休息一会 方便看数据


def consumer():   # 消费者
   while True:
      item = yield   # 切换到produce()运行
      print('消费者消费了', item)


c = consumer()
produce(c)
生产者生产了 83
消费者消费了 83
生产者生产了 99
消费者消费了 99
生产者生产了 79
消费者消费了 79
生产者生产了 27
消费者消费了 27
生产者生产了 97
消费者消费了 97

协程是在一个线程内的执行的,本质来说就是不同函数之间的切换调用。

对一个生成器必须要先next()让他执行到yield才能在send数据进去。

如果某一个协程被阻塞了,整个线程(进程)都被阻塞。任意时刻,只有一个协程在执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的高校科研信息管理系统实现了操作日志管理、字典管理、反馈管理、公告管理、科研成果管理、科研项目管理、通知管理、学术活动管理、学院部门管理、科研人员管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让高校科研信息管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值