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

并发编程重点:


1

2

3

4

5

6

7

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

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

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

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

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

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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 in range(10):

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

        t.start()

        t_li.append(t)

    for in t_li:

        t.join()

        

    print(‘主,end----‘)

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


1

2

3

4

5

6

7

8

9

10

11

from threading import Thread

def task(name):

    print(‘%s is running‘%name)

    print(‘end ---‘)

    

if __name__ == "__main__":

    for in range(10):

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

        t.start()

        

    print(‘主 end ---‘)

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

协程知识点:https://www.cnblogs.com/wj-1314/p/9040121.html

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

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


1

2

3

4

5

6

7

8

9

10

11

12

13

def consumer():

    while True:

        = yield

        print(‘消费:‘, x)

        

def producter():

    = consumer()

    next(c)

    for in range(10):

        print(‘生产:‘, i)

        c.send(i)

        

producter()

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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 in range(10):

        = Thread(target=task)

        t.start()

        

    time.sleep(10)

    event.set()

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

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 in range(10):

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

        t.start()

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


1

2

3

4

5

6

7

from threading import Timer

def hello(name):

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

    

if __name__ == "__main__":

    = Timer(5,hello,args=(‘james‘,))

    t.start()

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

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 in range(5):

        print(‘生产:‘,i)

        time.sleep(1)

        q.put(i)

        

if __name__ == "__main__":

    = 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 in range(5):

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

        time.sleep(1)

        q.put(i)

    q.join()

    

if __name__ == "__main__":

    = 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实现进程间通信;


1

2

3

4

5

6

7

8

9

10

11

from multiprocessing import Process,Pipe

def task(conn):

    conn.send(‘hello world‘)

    conn.close()

    

if __name__ == "__main__":

    parent_conn,child_conn = Pipe()

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

    p.start()

    p.join()

    print(parent_conn.recv())

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

# 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或者线程服务器,一个潜在的问题是,恶意的程序可能会发送大量的请求导致服务器崩溃,请写一个程序,避免此类问题;


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

# 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模块,实现一个支持同时处理多个客户端请求的服务器,要求每次启动一个新线程处理客户端请求;


1

2

3

4

5

6

7

8

9

socketserver模块类介绍

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

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

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

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

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

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

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

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

  


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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)

    = threading.Thread(target=server.serve_forever)

    t.start()

  

数据库重点:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

语法:

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是可变长字符类型;


1

2

3

4

5

6

create table student(

    ID int primary key auto_increment,

    sname varchar(16not null,

    gender enum(‘male‘,‘female‘not null default ‘female‘,

    credit varchar(32)

);

  

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


1

2

3

4

5

6

7

create table class(

    cid int primary key auto_increment,

    cname varchar(16not 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,删除该数据;


1

2

3

4

5

6

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表中,每个班级的学生数;


1

2

3

4

5

insert into student(sname,class_id) values

(‘james‘,1),

(‘durant‘,2),

(‘curry‘,3);

select count(IDfrom student;

  

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


1

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

  

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


1

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

  

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

# _*_ 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表;


1

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

  

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

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 |

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

原文地址:https://www.cnblogs.com/anzhangjun/p/9459131.html

时间: 2024-10-02 20:02:00

python 闯关之路四(下)(并发编程与数据库编程) 并发编程重点的相关文章

python 闯关之路一(语法基础)

1,什么是编程?为什么要编程? 答:编程是个动词,编程就等于写代码,那么写代码是为了什么呢?也就是为什么要编程呢,肯定是为了让计算机帮我们搞事情,代码就是计算机能理解的语言. 2,编程语言进化史是什么? 答:机器语言 ------>  汇编语言 ------> 高级语言  机器语言:由于计算机内部只能接受二进制代码,因此,用二进制代码0和1描述的指令称为机器指令,全部机器指令的集合构成计算机的机器语言,机器语言属于低级语言. 汇编语言:其实质和机器语言是相同的,都是直接对硬件操作,只不过指令采

the python challenge闯关记录

0 第零关 2**38 = 274877906944 下一关的url:http://www.pythonchallenge.com/pc/def/274877906944.html 1 第一关 移位计算,可以看出来是移动2位 def trans_str(s): inword = 'abcdefghijklmnopqrstuvwxyz' outword = 'cdefghijklmnopqrstuvwxyzab' transtab = str.maketrans(inword, outword)

python 全栈之路

python 全栈之路 一. python 1. Python基础知识部分 Python Python那点事 Python windows和linux下 安装 Python2,Python3 Python 开启入坑之路 Python 基本数据类型 Python 那些零碎的知识点 Python -函数 Python - 面对对象 Python - 模块 Python - 文件操作 Python - python中经常踩得的坑 2. Python - 网络编程 3. Python - 并发编程 二.

光棍节程序员闯关秀(总共10关)

程序员闯关大挑战: https://1111.segmentfault.com/ 仓鼠演示7k7k.4399小游戏: http://cdn.abowman.com/widgets/hamster/hamster.swf 第一关 提示: 从所有信息中找到进入下一关的方法 这一关很简单,即使没有任何web知识也能轻松通过.只要你懂得晃鼠标~~ 查看源代码会发现有这么一行: <p><astyle="color: #172024"href="?k=7a2546077

网页闯关游戏(riddle webgame)--游戏玩法和整体介绍

前言: 记得上大学那会, 有位传说中的大牛, 写了一个网页闯关类的游戏. 当时我们玩得不亦乐乎, 也是第一次接触到这种形式的游戏. 不过当时纯玩家心态, 并没有想过去创造一个. 最近想起这事, 突然想复制实现一个类似的网页闯关游戏. 说干就干, 抄起家伙, 就是一顿猛打, ^_^. 期间的坎坷曲折暂且不表, 甚至中途自觉江郎才尽差点放弃, 所幸最后终于完工, 愿意和大家一起分享该游戏. 展示: 网页闯关游戏, 更多的被称为riddle, 是一种考验搜索, 推理, 分析能力的闯关模式游戏. 用户群

网页闯关小游戏闯关记录(一)ISA TEST

在知乎上找到一个关于CTF入门的回答,答主很专业的给出了建议和一些对应的训练平台,这里我试了试几个,自己半吊子水平,只能玩一些简单的,这里把自己做的过程记录下来,这几个基本都能查到通关秘籍(我是怎么知道的?没错我太渣没法通关去查秘籍了),我写下来只当是自己的备忘,大牛请无视.... ISA TEST看起来貌似是深圳职业技术学院计算机学院信息安全协会做的一个闯关小游戏,一共7关,难度较低,我这种渣渣都能做,不过最后一关还是查了writeup. 第一关: 和类似闯关游戏的套路相同,第一关都很简单,密

Python之路:堡垒机实例以及数据库操作

Python之路:堡垒机实例以及数据库操作 一.堡垒机前戏 开发堡垒机之前,先学习Python的paramiko模块,该模块基于SSH用于连接远程服务器并执行相关操作. SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: #!/usr/bin/env  python# --*--coding:utf-8 --*--import paramiko #创建SSH对象ssh = paramiko.SSHClient()# 允许连接不在know_hosts文件中的主机ssh.se

网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点

前言: 之前编写了一个网页闯关游戏(类似Riddle Game), 除了希望大家能够体验一下我的游戏外. 也愿意分享编写这个网页游戏过程中, 学到的一些知识. 本文讲描述, 如何在网页端实现一个仿微信的聊天窗口界面, 以及其中涉及到的一些技术点. 作者前端是初学者, 请大拿们轻拍. 效果展示: 先打下广告: 网页闯关游戏入口(请狠狠地点击我, ^_^) . 仿微信窗口的设计源于第四关--倾听女神的故事. 这种聊天对话的布局模式, 比PC端QQ的那种聊天方式更贴近移动端, 我个人感觉. 需求设定:

射击闯关游戏,旧王已死、新王当立?

射击类游戏的最佳形态是电子竞技?比如<穿越火线> 街机.单机时代的<魂斗罗>.<合金装备>等闯关型射击游戏体验,不再适合移动手游时代? 射击类游戏需要更真实.更热血,最好如昆丁塔伦蒂洛的电影一样,拳拳到肉.血浆横飞?比如<使命召唤>? 曾经占据游戏机.单机和联机游戏极大份额的射击游戏们,在移动时代只能扮演有益补充? 射击类游戏混的似乎不太好?不是没有缘故的,根本原因就是长期自由搏击,而忘记了,其实关卡才是最能吸引用户的所在? 关卡.关卡.关卡!你还在自由搏击