python并发编程数据库_python 闯关之路四(下)(并发编程与数据库编程)

并发编程重点:

并发编程:线程、进程、队列、IO多路模型

操作系统工作原理介绍、线程、进程演化史、特点、区别、互斥锁、信号、

事件、join、GIL、进程间通信、管道、队列。

生产者消息者模型、异步模型、IO多路复用模型、select\poll\epoll 高性

能IO模型源码实例解析、高并发FTP server开发

1、请写一个包含10个线程的程序,主线程必须等待每一个子线程执行完成之后才结束执行,每一个子线程执行的时候都需要打印当前线程名、当前活跃线程数量;

from threading import Thread,currentThread,activeCount

import time

def task(n):

print('线程名:%s----%s'%(currentThread().name,n))

time.sleep(1)

print('数量:%s'%activeCount())

if __name__ == "__main__":

t_li = []

for i in range(10):

t = Thread(target=task,args=(i,))

t.start()

t_li.append(t)

for t in t_li:

t.join()

print('主,end----')

2、请写一个包含10个线程的程序,并给每一个子线程都创建名为"name"的线程私有变量,变量值为“james”;

from threading import Thread

def task(name):

print('%s is running'%name)

print('end ---')

if __name__ == "__main__":

for i in range(10):

t = Thread(target=task,args=('james_%s'%i,))

t.start()

print('主 end ---')

3、请使用协程写一个消费者生产者模型;

协程:单线程下,无法利用多核,可以是一个程序开多个进程,每个进程开启多个线程,每隔线程开启协程;

协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程。

def consumer():

while True:

x = yield

print('消费:', x)

def producter():

c = consumer()

next(c)

for i in range(10):

print('生产:', i)

c.send(i)

producter()

4、写一个程序,包含十个线程,子线程必须等待主线程sleep 10秒钟之后才执行,并打印当前时间;

from threading import Thread,Event

import time

import datetime

def task():

# while not event.is_set():

# print('...')

print('...')

event.wait(10)

print('time:',datetime.datetime.now())

if __name__ == '__main__':

event = Event()

for i in range(10):

t = Thread(target=task)

t.start()

time.sleep(10)

event.set()

5、写一个程序,包含十个线程,同时只能有五个子线程并行执行;

from threading import Thread,Semaphore,currentThread

import time

def task(n):

sm.acquire()

print('%s---'%n,currentThread().name)

time.sleep(1)

print('end----')

sm.release()

if __name__ == '__main__':

sm = Semaphore(5)

for i in range(10):

t = Thread(target=task,args=(i,))

t.start()

6、写一个程序 ,包含一个名为hello的函数,函数的功能是打印字符串“Hello, World!”,该函数必须在程序执行30秒之后才开始执行(不能使用time.sleep());

from threading import Timer

def hello(name):

print('%s say '%name,'Hello World!')

if __name__ == "__main__":

t = Timer(5,hello,args=('james',))

t.start()

7、写一个程序,利用queue实现进程间通信;

from multiprocessing import Process,Queue,current_process

import time

def consumer(q):

while True:

res = q.get()

if not res:break

print('消费了:',res,'--',current_process().name)

def producter(q):

for i in range(5):

print('生产:',i)

time.sleep(1)

q.put(i)

if __name__ == "__main__":

q = Queue()

p1 = Process(target=producter,args=(q,))

c1 = Process(target=consumer,args=(q,))

c2 = Process(target=consumer,args=(q,))

p1.start()

c1.start()

c2.start()

p1.join()

q.put(None)

q.put(None)

print('主')

# JoinableQueue

from multiprocessing import Process,JoinableQueue,current_process

import time

def consumer(q):

while True:

res = q.get()

print('消费了:',res,'--',current_process().name)

q.task_done()

def producter(q):

for i in range(5):

print('生产:',i,'--',current_process().name)

time.sleep(1)

q.put(i)

q.join()

if __name__ == "__main__":

q = JoinableQueue()

p1 = Process(target=producter,args=(q,))

p2 = Process(target=producter, args=(q,))

c1 = Process(target=consumer,args=(q,))

c2 = Process(target=consumer,args=(q,))

p1.start()

p2.start()

c1.daemon = True

c2.daemon = True

c1.start()

c2.start()

p1.join()

p2.join()

print('主')

8、写一个程序,利用pipe实现进程间通信;

from multiprocessing import Process,Pipe

def task(conn):

conn.send('hello world')

conn.close()

if __name__ == "__main__":

parent_conn,child_conn = Pipe()

p = Process(target=task,args=(child_conn,))

p.start()

p.join()

print(parent_conn.recv())

9、使用selectors模块创建一个处理客户端消息的服务器程序;

# server blocking IO

import socket

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server.bind(('127.0.0.1',8080))

server.listen(5)

while True:

conn,addr = server.accept()

print(addr)

while True:

try:

data = conn.recv(1024)

if not data: break

conn.send(data.upper())

except Exception as e:

print(e)

break

# server IO多路复用 selectors 会根据操作系统选择select poll epoll

import socket

import selectors

sel = selectors.DefaultSelector()

def accept(server_fileobj,mask):

conn,addr = server_fileobj.accept()

print(addr)

sel.register(conn,selectors.EVENT_READ,read)

def read(conn,mask):

try:

data = conn.recv(1024)

if not data:

print('closing..',conn)

sel.unregister(conn)

conn.close()

return

conn.send(data.upper())

except Exception:

print('closeing...',conn)

sel.unregister(conn)

conn.close()

server_fileobj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server_fileobj.bind(('127.0.0.1',8080))

server_fileobj.listen(5)

server_fileobj.setblocking(False)

sel.register(server_fileobj,selectors.EVENT_READ,accept)

while True:

events = sel.select()

for sel_obj,mask in events:

callback = sel_obj.data

callback(sel_obj.fileobj,mask)

# client

# -*- coding:utf-8 -*-

import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

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

while True:

msg = input('>>>:').strip()

if not msg:continue

client.send(msg.encode('utf-8'))

data = client.recv(1024)

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

10、使用socketserver创建服务器程序时,如果使用fork或者线程服务器,一个潜在的问题是,恶意的程序可能会发送大量的请求导致服务器崩溃,请写一个程序,避免此类问题;

# server socketserver 模块内部使用IO多路复用 和多进程/多线程

import socketserver

class Handler(socketserver.BaseRequestHandler):

def handle(self):

print('new connection:',self.client_address)

while True:

try:

data = self.request.recv(1024)

if not data:break

print('client data:',data.decode())

self.request.send(data.upper())

except Exception as e:

print(e)

break

if __name__ == "__main__":

server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),Handler)

server.serve_forever()

11、请使用asyncio实现一个socket服务器端程序;

12、写一个程序,使用socketserver模块,实现一个支持同时处理多个客户端请求的服务器,要求每次启动一个新线程处理客户端请求;

socketserver模块类介绍

SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,

从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求

连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进 程”

专门负责处理当前客户端的所有请求。

socketserver模块可以简化网络服务器的编写,python把网络服务抽

象成两个主要的类,一个是server类,用于处理连接相关的网络操作,另一个

是RequestHandler类,用于处理数据相关的操作。并且提供两个Mixln类,

用于扩展server,实现多进程或者多线程。

import socketserver

import threading

class MyServer(socketserver.BaseRequestHandler):

def handle(self):

while True:

self.data = self.request.recv(1024).decode()

print(self.data)

self.request.send(self.data.upper().encode())

if __name__ == '__main__':

server = socketserver.ThreadingTCPServer(('127.0.0.1', 9999), MyServer)

t = threading.Thread(target=server.serve_forever)

t.start()

数据库重点:

1、数据库介绍、类型、特性

2、MySQL数据库安装、连接、启动、停止

3、表字段类型介绍、主键约束、表创建语句

4、常用增删改查语句、分组、聚合

5、外键管理、unique字段、表结构修改语法

6、跨表查询,inner join、left join、right join、full join语法

7、复杂SQL语句如group by、子查询、函数的使用

8、索引原理及作用、普通索引、多列索引、唯一索引、全文索引等

9、基于hash&b+树索引的实现原理,索引的优缺点剖析

10、事务原理,ACID特性,应用场景讲解

11、事务回滚

12、触发器的特性,应用场景

13、触发器的增删改查方法

14、存储过程的作用及应用场景

15、创建存储过程,参数传递,流程控制语句if\while\repeat\loop等,动态SQL的创建

16、视图的作用及使用场景,视图的增删改查

17、数据库权限管理,用户管理

18、数据库备份命令及工具讲解

19、基于不同业务的数据库表结构设计、性能优化案例

20、pymysql模块介绍和使用

修改表结构的语法

语法:

1. 修改表名

ALTER TABLE 表名

RENAME 新表名;

2. 增加字段

ALTER TABLE 表名

ADD 字段名 数据类型 [完整性约束条件…],

ADD 字段名 数据类型 [完整性约束条件…];

ALTER TABLE 表名

ADD 字段名 数据类型 [完整性约束条件…] FIRST;

ALTER TABLE 表名

ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;

3. 删除字段

ALTER TABLE 表名

DROP 字段名;

4. 修改字段

ALTER TABLE 表名

MODIFY 字段名 数据类型 [完整性约束条件…];

ALTER TABLE 表名

CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];

ALTER TABLE 表名

CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

1、创建一个表student,包含ID(学生学号),sname(学生姓名),gender(性别),credit(信用卡号),四个字段,要求:ID是主键,且值自动递增,sname是可变长字符类型,gender是枚举类型, credit是可变长字符类型;

create table student(

ID int primary key auto_increment,

sname varchar(16) not null,

gender enum('male','female') not null default 'female',

credit varchar(32)

);

2、在上面的student表中增加一个名为class_id的外键,外键引用class表的cid字段;

create table class(

cid int primary key auto_increment,

cname varchar(16) not null

);

alter table student add class_id int not null;

alter table student add foreign key(class_id) references class(cid) on delete cascade on update cascade;

3、向该表新增一条数据,ID为1,学生姓名为alex,性别女,修改ID为1的学生姓名为wupeiqi,删除该数据;

insert into class(cname) values

('一班'),

('二班');

insert into student values(1,'alex','female','12345',1);

update student set sname = 'wupeiqi' where id = 1;

delete from student where id = 1;

4、查询student表中,每个班级的学生数;

insert into student(sname,class_id) values

('james',1),

('durant',2),

('curry',3);

select count(ID) from student;

5、修改credit字段为unique属性;

alter table student modify credit varchar(32) not null unique;

6、请使用命令在你本地数据库中增加一个用户,并给该用户授予创建表的权限;

grant create on *.* to 'james'@'localhost' identified by '123';

7、请使用pymsql模块连接你本地数据库,并向student表中插入一条数据;

# _*_ coding: utf-8 _*_

# 7、请使用pymsql模块连接你本地数据库,并向student表中插入一条数据;

import pymysql

conn = pymysql.connect(

host = '127.0.0.1',

port = 3306,

user = 'root',

password = '******',

db = 'test622',

charset = 'utf8'

)

cursor = conn.cursor()

sql = "insert into student values(13,'park','男','123456',1)"

rows = cursor.execute(sql)

conn.commit()

cursor.close()

conn.close()

8、请使用mysqldump命令备份student表;

mysqldump -uroot -p123 db_bj student > /home/bj/桌面/myfile/student.sql

9、创建一张名为student_insert_log的表,要求每次插入一条新数据到student表时,都向student_insert_log表中插入一条记录,记录student_id, insert_time;

mysql> desc student;

+----------+-----------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+----------+-----------------------+------+-----+---------+----------------+

| ID | int(11) | NO | PRI | NULL | auto_increment |

| sname | varchar(16) | NO | | NULL | |

| gender | enum('male','female') | NO | | female | |

| credit | varchar(32) | NO | UNI | NULL | |

| class_id | int(11) | NO | MUL | NULL | |

+----------+-----------------------+------+-----+---------+----------------+

create table student_insert_log(

student_id int not null,

insert_time datetime not null

);

创建一个触发器:

delimiter //

create trigger tri_after_insert_student after insert on student for each row

begin

insert into student_insert_log values(new.ID,now());

end //

delimiter ;

insert into student(sname,credit,class_id) values ('alice','123',2);

insert into student(sname,credit,class_id) values

('egon1','1234',1),

('egon2','12345',2);

mysql> select * from student;

+----+-------+--------+---------+----------+

| ID | sname | gender | credit | class_id |

+----+-------+--------+---------+----------+

| 4 | alcie | female | 123456 | 1 |

| 7 | alcie | female | 1234567 | 1 |

| 8 | alice | female | 123 | 2 |

| 9 | egon1 | female | 1234 | 1 |

| 10 | egon2 | female | 12345 | 2 |

+----+-------+--------+---------+----------+

mysql> select * from student_insert_log;

+------------+---------------------+

| student_id | insert_time |

+------------+---------------------+

| 8 | 2018-04-24 21:29:46 |

| 9 | 2018-04-24 21:32:05 |

| 10 | 2018-04-24 21:32:05 |

+------------+---------------------+

10、创建一张名为student_update_log的表,要求每次更新student表中的记录时,都向student_update_log表中插入一条记录,记录student_id, update_time;

create table student_update_log(

student_id int not null,

update_time datetime

);

创建一个触发器

delimiter //

create trigger tri_after_update_student after update on student for each row

begin

insert into student_update_log values(new.ID,now());

end //

delimiter ;

show triggers\G;

update student set sname = 'alex' where ID in (9,10);

mysql> select * from student;

+----+-------+--------+---------+----------+

| ID | sname | gender | credit | class_id |

+----+-------+--------+---------+----------+

| 4 | alcie | female | 123456 | 1 |

| 7 | alcie | female | 1234567 | 1 |

| 8 | alice | female | 123 | 2 |

| 9 | alex | female | 1234 | 1 |

| 10 | alex | female | 12345 | 2 |

+----+-------+--------+---------+----------+

5 rows in set (0.00 sec)

mysql> select * from student_update_log;

+------------+---------------------+

| student_id | update_time |

+------------+---------------------+

| 9 | 2018-04-24 21:47:24 |

| 10 | 2018-04-24 21:47:24 |

+------------+---------------------+

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值