欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

数据库 tcp协程实现并发 回调函数

程序员文章站 2022-06-27 21:33:30
数据库 tcp协程实现并发 回顾 一、回顾 进程池,线程池,回调函数 二、tcp服务端实现协程 演示 三、数据库安装以及修改配置等操作 理论知识加语法 ......

数据库 tcp协程实现并发 回顾

一、回顾

  • 进程池,线程池,回调函数
# from gevent import monkey;monkey.patch_all()  #补丁
from gevent import spawn
import time


# def task1(name):
#     print(name)
#     print('start')
#     time.sleep(1)
#     print('end')
#
#
# def task2():
#     print('start')
#     time.sleep(3)
#     print('end')
#
#
# def task3():
#     print('start')
#     time.sleep(5)
#     print('end')
#
#
# if __name__ == '__main__':
#     spawn(task1, 'tank')
#     spawn(task2)
#     g = spawn(task3)
#     g.join()

#线程池与进程池

# #进程池
# from concurrent.futures import processpoolexecutor,threadpoolexecutor
#
# #池子对象:内部帮你提交50个启动进程的任务
# p_pool = processpoolexecutor(50)
#
#
# def task1(n):
#     print(f'from task1...{n}')
#     time.sleep(10)
#
#
# if __name__ == '__main__':
#     n = 1
#     while true:
#         #参数1:函数名
#         #参数2:函数的参数1
#         #参数3:函数的参数2
#         #submit(参数1,参数2, 参数3)
#         p_pool.submit(task1, n)
#         n += 1
#
#         ##注意:还有一个shutdown的用法,是用来关闭进程池以及提交的任务submit的
#
#

# # 线程池
# from concurrent.futures import threadpoolexecutor
# import time
# ## 池子对象:内部可以帮你提交50个启动线程的任务
# p_pool =  threadpoolexecutor(50)
#
#
# def task1(n):
#     print(f'from task1...{n}')
#     time.sleep(10)
#
#
# if __name__ == '__main__':
#     n = 1
#     while true:
#         p_pool.submit(task1, n)
#         n += 1

#add_done_callback
from concurrent.futures import threadpoolexecutor
import time

p_pool = threadpoolexecutor(50)


def task1(n):
    print(f'from task1...{n}')
    time.sleep(5)
    return 'yafeng'


def get_result(obj):
    # print(obj.__dict__)
    #print(obj._result)   等同于 print(obj.)
    result = obj.result()
    print(result)



if __name__ == '__main__':
    n = 1
    while true:
        p_pool.submit(task1, n).add_done_callback(get_result)
        n += 1

二、tcp服务端实现协程

  • 演示
- client文件
from threading import thread, current_thread
import socket

def send_get_msg():
    client = socket.socket()

    client.connect(
        ('127.0.0.1', 9026)
    )

    while true:
        client.send(f'{current_thread().name}'.encode('utf-8'))
        data = client.recv(1024)
        print(data.decode('utf-8'))


if __name__ == '__main__':
    list1 = []
    for line in range(100):
        t = thread(target=send_get_msg)
        t.start()
        list1.append(t)


    for t in list1:
        t.join()


        
- sever 文件
from gevent import monkey;monkey.patch_all()
from gevent import spawn
import socket

sever = socket.socket()

sever.bind(
    ('127.0.0.1', 9026)
)

sever.listen()

#与客户端通信
def working(coon):
    while true:
        try:
            data = coon.recv(1024)
            if len(data) == 0:
                break

            print(data.decode('utf-8'))

            coon.send(data.upper())

        except exception as e:
            print(e)
            break
    coon.close()


#与客户端连接
def run(sever):
    while true:
        coon, addr = sever.accept()
        print(addr)
        spawn(working, coon)

if __name__ == '__main__':
    print('服务端已启动...')
    g = spawn(run, sever)
    g.join()

三、数据库安装以及修改配置等操作

  • 理论知识加语法
回顾:
    1、gil全局解释器锁
        - 优点:
            - 保证了数据安全
            - 因为cpython中的内存管理员不是线程安全的

        - 缺点:
            - 牺牲了效率,让线程无法实现并行。

    2、协程
        - 进程:资源单位
        - 线程:执行单位
        - 协程:单线程下实现并发

        - 人为模拟多道技术的 切换+保存状态
            - 切换:
                - io
                - 执行时间长

            - 保存状态:
                - yield

            - gevent模块

数据库:

    - 数据库的介绍:

        1、随意存放在一个文件中的数据,数据的格式千差万别
            tank|123 yafeng:666 reba-666

        2、软件开发规范目录
            - project:
                - conf
                - bin
                - core
                - db: 存放一个个的文件

        注意:1、2都是从本地读取的文件

        3、将所有的数据存放到一个第三方的公共位置,同一个软件凡是需要操作数据的,就必须去这个共享的位置去获取。

            - 第三方的共享位置(数据库)

            - 数据库集群:将同一个数据库中的数据,复制到不同的服务器中

        4、mysql数据:  c--->s 架构的软件
            1)mysql数据库本质上就是一个基于网络通信的软件
            2)所有基于网络通信的软件,底层都是socket

            - 服务端:
                - 基于网络通信
                - 收发消息

            - 客户端:
                - 基于网络通信
                - 收发消息

            - 所有语言若想操作数据库,拿到服务端ip和port,都必须遵循一套标准的解析指令


            *******重点:学习sql语句

            - dbms:数据库管理系统

                - 关系型数据库:mysql、oracle、db2、sqlsever、。。。
                    - 1) 表结构
                        - 需要哪些字段
                        - 字段是什么类型

                    - 2) 字段与字段类型
                        - name --->"tank"--->字符串
                        - age--->17--->整型

                - 非关系型数据库:redis、mongodb...
                    - 非关系型数据库一般以key:value 的形式存储

                    {'naem':'tank'}


     - 安装数据库
        - 1、下载mysql安装包(直接去官网下载最好不要下载最新版本)
        - 2、解压安装包放在你想要放的盘中
        - 3、添加系统环境变量(拷贝bin的地址)
        - 4、以管理员就身份打开cmd,输入mysql启动服务端,此时会卡主
            - mysql初始化是无密码,可以进入游客模式,功能会很少
            - 无密码直接进入--->不需要-p密码
            - bin目录相下的:mysql.exe(想当于客户端)
                           mysqld.exe(相当于服务端)

            全写:mysql -h 127.0.0.1 -p 3306 -p 密码
            简写:mysql -uroot -p 密码

        5、退出数据库客户端
            - exit;
            - quit

        注意:sql语句末尾必须加“;”号。

        - 查看操作系统中是否已经启动mysql服务端
            - tasklist | findstr "mysql"

        - 杀死mysql进程
            - taskkill /f /pid pid号

        - *******做服务端时,必须先以管理员身份运行

        - 数据库的命令:
            - 查看所有的数据库
                - show databases;

        - 制作系统服务
            - 1、必须将已启动过的服务端的mysql关掉
            - 2、kill掉已启动的mysql的进程
            - 3、输入 mysql --install ---->安装mysql系统服务
            - 4、输入 net start mysql  # 这是打开mysql服务
                      net stop mysql  #这是关闭mysql服务


            mysql -u 登录mysql用户名(一般是root) -p 密码
                - 默认自带 root 超级用户,没有密码
                - 管理员登录
                    - mysql -uroot  回车进入

                - 游客登录
                    - mysql 回车

                - 修改密码:
                    - 默认没有密码的情况下,设置密码
                        - cmd>>>:mysqladmin -uroot password 123

                    - 有密码的情况下,修改密码
                        - cmd>>>:mysqladmin -uroot -p原密码 password你要修改的密码
                        - cmd>>>:mysqladmin _uroot -p123 password 123456

                    - 破解密码:当密码忘记时采用
                        - 1、关闭服务端
                        - 2、跳过权限启动服务端
                            -cmd>>>: mysql --skip-grant-tables

                        - 3、客户端进入游客模式:
                            - cmd>>>: mysql

                            - update mysql库.user表名 set 字段password=字段password('字段值') where 条件(若条件成立,则修改)user=“root”;
                            - cmd>>>: update mysql.user set password= password('123456') where user="root";

                        - 4、重新启动服务端,不要跳过权限认证
                            - 先kill掉跳过权限认证启动的服务端进程
                            - 在手动去开服务服务中的mysql服务即可

                        - 设置配置文件:
                            - 1、先在mysql目录下 ---> 找到你的默认的default配置文件

                            - 2、创建一个名为“my.ini”的文件夹,这是mysql的配置文件
                                 -   [mysqld]
                                     character-set-server=utf8
                                     collation-server=utf8_general_ci

                                    # 这个是用python软件连接的客户端
                                     [client]
                                     default-character-set=utf8


                                    # mysql软件的客户端
                                     [mysql]
                                    # 可写,可不写这样可以不需要用户名与密码直接登录mysql
                                    # user='root'
                                    # password=123

                                    # 设置默认的字符编码
                                     default-character-set=utf8

                            - 3、重启mysql服务,修改成功!

                        数据库的基本操作:
                            - 库的操作 ---> 类似于文件夹
                                - 增:
                                    语法:create database 服务;
                                         create database db1;

                                - 查:
                                    语法:show databases;  #查看所有的库
                                          show create database db1;  #查看db1库中的信息

                                - 改:
                                    语法:alter database 库名 charset="字符编码类型";
                                        - alter database db1 charset="utf8"  # 注意:不能写成“utf-8”

                                - 删
                                    语法:drop database db1;


                            - 表的操作 --->类似于文件
                                -*****注意:操作表前,需要先切换到指定的库擦才可以操作
                                    语法: use 库名;
                                        - use db1;

                                    查看当前所在的库:select database()

                                - 增
                                    varchar 与 char 都是字符串类型
                                    varchar(20)
                                    语法:create table 表名(字段名 字段类型);
                                          create table user_info(name varchar(20), age int);
                                     #此时得先use user_info;才可以增加表名

                                - 改:
                                    语法:alter table 表名 modify name varchar(28);
                                         - alter table user_info modify name varchar(28);

                                - 删:
                                    语法:drop table 表名;
                                        - create table test(id int);
                                        - drop table test;

                            - 表中内容(数据)的操作 --->类似于文件中的一行行数据

                                - 增:
                                    语法:insert into 表名 values('字段类型的数据1', 字段类型的数据1);
                                    # 插入一条:
                                        - insert into user_info values('yafeng', 18);

                                    # 插入多条:
                                        - insert into user_info values('yafeng', 18), ('reba', 17);

                                - 查:
                                    # 注意:* 代表的是所有的意思
                                    语法:select * from 表名;  #查看表中所有的数据
                                        - select * from user_info;

                                    # 查看name 字段为 yafeng 的记录
                                        - select * from 表名 where 条件;  #条件成立则查看成功!
                                        - select *from user_info where name="yafeng";


                                    # 查看name 字段为 yafeng 的age字段
                                        - select age from user_info where name="yafeng";

                                    # 查看所有的名字:
                                        - select name from user_info;


                                - 改
                                    语法: update 表名 set 字段名=字段值 where 条件判断;  # 若条件成立,则修改成功!

                                    # 修改age为17的记录中的name属性为 handsome
                                    - update user_info set name="handsome" where age=17;

                                    # 修改age>16的记录中的记录 中的name属性为 d_sb
                                    - update user_info set name="d_sb" where age>16;

                                - 删

                                    语法:delete from 表名;
                                        # 清空表记录,不提交,可恢复。
                                        - delet from user_info;

                                    语法:truncate table 表名;
                                    #删除,不可恢复
                                    - truncate table user_info;