Linux:python数据库(mysql),多线程以及套接子(socket)

一·数据库(mysql)

什么是MySQLdb?

MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的。

1·安装MySQLdb以及与python的联系

首先配置好yum源进行配置环境:
[root@foundation41 kiosk]# yum install mariadb-server -y  安装服务
[root@foundation41 kiosk]# systemctl start mariadb  开启服务
[root@foundation41 kiosk]# systemctl status mariadb  查看服务状态
[root@foundation41 kiosk]# systemctl stop firewalld  关闭防火墙
[root@foundation41 kiosk]# mysql_secure_installation  重置密码

Set root password? [Y/n] 
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!
[root@foundation41 kiosk]# mysql -uroot -p  登陆
[root@foundation41 kiosk]# yum install gcc -y  安装
[root@foundation41 kiosk]# yum search MySQL-python
[root@foundation41 kiosk]# yum install MySQL-python.x86_64 -y  安装服务
[root@foundation41 kiosk]# pip install Mysql-Python  建立连接
在pycharm中导入import MySQLdb即可

pycharm:这里写图片描述

2·搭建网页版的数据库管理

将安装包phpMyAdmin-3.4.0-all-languages.tar.bz2放到/car/www/html/目录下
[root@foundation41 Desktop]#yum install httpd php php-mysql -y
[root@foundation41 Desktop]# cd /var/www/html/
[root@foundation41 html]# ls
phpMyAdmin-3.4.0-all-languages.tar.bz2  source7.3 
[root@foundation41 html]# tar jxf phpMyAdmin-3.4.0-all-languages.tar.bz2 
[root@foundation41 html]# ls
phpMyAdmin-3.4.0-all-languages          source7.3
phpMyAdmin-3.4.0-all-languages.tar.bz2
[root@foundation41 html]# rm -fr phpMyAdmin-3.4.0-all-languages.tar.bz2 
[root@foundation41 html]# ls
phpMyAdmin-3.4.0-all-languages  source7.3
[root@foundation41 html]# mv phpMyAdmin-3.4.0-all-languages/ mysqladmin
[root@foundation41 html]# ls
mysqladmin  source7.3
[root@foundation41 html]# cd mysqladmin/
[root@foundation41 mysqladmin]# cp config.sample.inc.php config.inc.php

在网页中输入172.25.41.250/mysqladmin
这里写图片描述

3·建立数据库的管理:

[root@foundation41 kiosk]# mysql -uroot -p
Enter password: 

MariaDB [(none)]> show databases;     ##查看数据库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

MariaDB [(none)]> create database python;    ##建立数据库python
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| python             |
+--------------------+
4 rows in set (0.00 sec)

MariaDB [(none)]> use python;   ##进入数据库python
Database changed

MariaDB [python]> create table userInfo(id int,name varchar(10));    ##建立表
Query OK, 0 rows affected (0.01 sec)

MariaDB [python]> show tables;   ##查看表
+------------------+
| Tables_in_python |
+------------------+
| userInfo         |
+------------------+
1 row in set (0.00 sec)

MariaDB [python]> select * from userInfo;    ##显示表的所有内容
Empty set (0.00 sec) 

MariaDB [python]> insert into userInfo(id,name)value(1,'tom');   ##添加id和name
Query OK, 1 row affected (0.00 sec)

MariaDB [python]> select * from userInfo;
+------+------+
| id   | name |
+------+------+
|    1 | tom  |
+------+------+
1 row in set (0.00 sec)

MariaDB [python]> Bye

这里写图片描述这里写图片描述

4·建立好数据库和python连接之后直接导入import MySQLdb即可

数据库基本格式:

MySQL 数据库
host : MySQL 数据库地址
user: 数据库登陆用户名
passwd: 数据库登陆密码
db:登陆数据库后,需要操作的库名
port: 数据库监听端口,默认为 3306
charset: 数据库编码
MySQL连接操作
commit():如果数据库表进行了修改,提交保存当前的数据。
rollback(): 如果有权限,就取消当前的操作,否则报错 cursor() 游标指针。

1.查询
(1)查询数据库(只输出改变了几行)

# _*_ coding:utf-8 _*_
"""
file:查(只输出改变了几行).py
date:2018-07-25 1:19 AM
author:Jiong
desc:


"""
import MySQLdb
# 打开门
# 127.0.0.1:回环接口
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')

# 伸出手
cur = conn.cursor()

# 拿东西
recont = cur.execute('select * from userInfo')

# 把手伸回来
cur.close()

# 把门关上
conn.close()

print recont

这里写图片描述

(2)查询数据库(返回值)

# _*_ coding:utf-8 _*_
"""
file:查(返回值).py
date:2018-07-25 2:28 AM
author:Jiong
desc:


"""
import MySQLdb
# 打开门
# 127.0.0.1:回环接口
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')

# 伸出手
# 查看值
cur = conn.cursor()  # 创建了一个“手”

# 拿东西
# 这个操作影响了多少行数(有所少行被操作了)
recont = cur.execute('select * from userInfo')
data = cur.fetchall()

# 把手伸回来
cur.close()

# 把门关上
conn.close()

print recont
print data

这里写图片描述
(3)查询数据库(字典输出)

# _*_ coding:utf-8 _*_
"""
file:查(字典输出).py
date:2018-07-25 2:58 AM
author:Jiong
desc:


"""
import MySQLdb
# 打开门
# 127.0.0.1:回环接口
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')

# 伸出手
# 查看数据库的表头
cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)

# 拿东西
# 这个操作影响了多少行数(有所少行被操作了)
recont = cur.execute('select * from userInfo')
data = cur.fetchall()

# 把手伸回来
cur.close()

# 把门关上
conn.close()

print recont
print data

这里写图片描述

2.增加
在网页数据库中建立一个新的表
这里写图片描述

# _*_ coding:utf-8 _*_
"""
file:增.py
date:2018-07-25 2:57 AM
author:Jiong
desc:


"""
import MySQLdb
# 打开门
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')

# 伸出手
cur = conn.cursor()

# 操作数据
sql = 'insert into usermg(id,name,address) values(%s,%s,%s)'
params = ('1','jiong','usa')
recount = cur.execute(sql,params)

# 提交请求
conn.commit()

# 把手伸回来
cur.close()

# 把门关上
conn.close()
print recount

这里写图片描述
在网页中查看是否添加成功
这里写图片描述

3.删除

# _*_ coding:utf-8 _*_
"""
file:删.py
date:2018-07-25 2:57 AM
author:Jiong
desc:


"""
import MySQLdb
# 打开门
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')

# 伸出手
cur = conn.cursor()

# 操作数据
sql = 'delete from usermg where id = %s'
params = (1,)
recount = cur.execute(sql,params)

# 提交请求
conn.commit()

# 把手伸回来
cur.close()

# 把门关上
conn.close()
print recount

这里写图片描述这里写图片描述

4.更改
首先执行增加后再执行更改

# _*_ coding:utf-8 _*_
"""
file:改.py
date:2018-07-25 2:58 AM
author:Jiong
desc:


"""
import MySQLdb
# 打开门
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')

# 伸出手
cur = conn.cursor()

# 操作数据
sql = 'update usermg set name = %s where id = %s'
params = ('ll','1')
recount = cur.execute(sql,params)

# 提交请求
conn.commit()

# 把手伸回来
cur.close()

# 把门关上
conn.close()
print recount

这里写图片描述
这里写图片描述

5.事务操作
在网页建立新的数据表并插入字段信息
这里写图片描述这里写图片描述这里写图片描述

# _*_ coding:utf-8 _*_
"""
file:mysql_事务.py
date:2018-07-25 5:51 AM
author:Jiong
desc:
提交和回滚,在数据库里叫事务操作
在同一张数据表一增一减时若有一个出现错误,则两个都不会执行,会返回原来的结果,这种操作叫做回滚,不会出现数据丢失的情况。
"""
import MySQLdb
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')
cur = conn.cursor()

sql = 'update money set money = %s where id = 1'
params = ('0',)
recount = cur.execute(sql,params)

sql = 'update money set money = %s where id = 2'
param = ('100',)
recount = cur.execute(sql,param)
conn.commit()

这里写图片描述
这里写图片描述

6.插入多条数据

# _*_ coding:utf-8 _*_
"""
file:插入多条数据.py
date:2018-07-25 3:38 AM
author:Jiong
desc:


"""
import MySQLdb
# 打开门
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='python')

# 伸出手
cur = conn.cursor()

# 操作数据
#sql = 'insert into usermg(id,name,address) values(%s,%s,%s)'
#params = ('1','jiong','usa')
li = [
    ('2','hahaha','www'),
    ('3','lalala','qqq'),
]
recount = cur.executemany('insert into usermg(id,name,address) values(%s,%s,%s)',li)

# 提交请求
conn.commit()

# 把手伸回来
cur.close()

# 把门关上
conn.close()
print recount

这里写图片描述
这里写图片描述

二·多线程

多线程能干什么: 生产者消费者问题:(经典) 一直生产 一直消费 中间有阀值 避免供求关系不平衡

线程安全问题,要是线程同时来,听谁的 锁:一种数据结构 队列:先进线出 栈:先进后出

生产者消费者的优点(为什么经典的设计模式)
1.解耦(让程序各模块之间的关联性降到最低) 假设生产者和消费者是两个类,如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合),
如果将来消费者的代码发生变换,可能会影响到生产者,而如果两者都依赖于某个缓冲区,两者之间不直接依赖, 耦合也就相应降低了
生活中的例子:我们 邮筒 邮递员 举个例子,我们去邮局投递信件,如果不使用邮筒(也就是缓冲区),你必须得把信直接交给邮递员,有同学会说,
直接交给邮递员不是挺简单的嘛,其实不简单,你必须得认识邮递员,才能把信给他(光凭身上的制服,万一有人假冒呢???),
这就产成你和邮递员之间的依赖了(相当于生产者消费者强耦合),万一哪天邮递员换人了,
你还要重新认识一下(相当于消费者变化导致修改生产者代码),而邮筒相对来说比较固定, 你依赖它的成本就比较低(相当于和缓冲区之间的弱耦合)
2.支持并发 生产者消费者是两个独立的并发体,他们之间是用缓冲区作为桥梁连接,生 产者之需要往缓冲区里丢数据,就可以继续生产下一个数据,而消费者者只需要从缓冲区里拿数据即可, 这样就不会因为彼此速度而发生阻塞
接着上面的例子:如果我们不使用邮筒,我们就得在邮局等邮递员,直到他回来了,我
们才能把信给他,这期间我们啥也不能干(也就是产生阻塞),或者邮递员挨家挨户的问(产生论寻)
3.支持忙闲不均 如果制造数据的速度时快时慢,缓冲区的好处就体现出来了,当数据制造快的时候, 消费者来不及处理,未处理的数据可以暂时存在缓冲区中,等生产者的速度慢下来, 消费者再慢慢处理
情人节信件太多了,邮递员一次处理不了,可以放在邮筒中,下次在来取

多线程类似于同时执行多个不同程序,多线程运行有如下优点:

(1)使用线程可以把占据长时间的程序中的任务放到后台去处理。
(2)用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 (3)程序的运行速度可能加快 (4)
在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

线程在执行过程中与进程还是有区别的:

。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。
指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。

线程可以被抢占(中断)。
在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) – 这就是线程的退让。

1.一个简单的多任务问题

从执行结果看到,只会在一个任务完成了之后才会进行下一个任务,效率低下

# _*_ coding:utf-8 _*_
"""
file:1.py
date:2018-07-26 7:44 AM
author:Jiong
desc:


"""
from time import ctime, sleep
def music(a):
    for i in range(2):
        print 'I was listening to %s. %s' % (a, ctime())
        sleep(2)
def movie(b):
    for i in range(2):
        print 'I was listening to %s. %s' % (b, ctime())
        sleep(5)
music('告白气球')
movie('泰坦尼克号')
print 'all over %s' % ctime()

这里写图片描述

2.线程

(1)

# _*_ coding:utf-8 _*_
"""
file:多线程_2.py
date:2018-07-25 6:33 AM
author:Jiong
desc:
线程是操作系统能够进行运算调度的最小单位(程序执行流的最小单元)
它被包含在进程之中,是进程中的实际运作单位.一个进程中可以并发多个线程
每条线程并执行不同的任务
(线程是进程中的一个实体是被系统独立调度和分派的基本单元)

每个进程启动时都会最先产生一个线程,即主线程
然后主线程再创建其他的子线程

"""
from threading import  Thread
def Foo(arg):
    print arg

print 'before'
# 线程和函数建立关系
t1 = Thread(target=Foo,args=(1,))
t1.start()
print 'after'

这里写图片描述

(2)

# _*_ coding:utf-8 _*_
"""
file:多线程_3.py
date:2018-07-25 6:36 AM
author:Jiong
desc:


"""
from threading import Thread
def Foo(arg):
    print arg

print 'before'
t1 = Thread(target=Foo,args=(1,))
t1.start()
print t1.getName()

t2 = Thread(target=Foo,args=(2,))
t2.start()
print t2.getName()

print 'after'

这里写图片描述

(3)加入了t1.setDaemon(True)
意味着主线程不需要等待子线程啥时候结束就可以结束 但是会等到子线程结束之后一起销毁

# _*_ coding:utf-8 _*_
"""
file:多线程_4.py
date:2018-07-25 6:51 AM
author:Jiong
desc:


"""
from threading import Thread
import time
def Foo():
    for item in range(50):
        print item
        time.sleep(1)
print 'before'
t1 = Thread(target=Foo)
# 主线程执行完,不管子线程有没有执行完
# 不等子线程结束,主线程直接结束
t1.setDaemon(True)
t1.start()
print  'after'
time.sleep(5)

这里写图片描述

(4)加入了t1.join(5)
表示主线程到join()就不往下走了,直到子线程进行完成

# _*_ coding:utf-8 _*_
"""
file:多线程_5.py
date:2018-07-25 7:08 AM
author:Jiong
desc:


"""
from threading import Thread
import time
def Foo():
    for item in range(10):
        print item
        time.sleep(1)
print 'before'
t1 = Thread(target=Foo)
t1.start()
# 主线程到join()就不往下走了
t1.join()
# t1.join(5)
print 'after'

这里写图片描述

3.返回第一个文件提高效率

# _*_ coding:utf-8 _*_
"""
file:多线程_1.py
date:2018-07-25 6:05 AM
author:Jiong
desc:


"""
from time import ctime,sleep
import threading
def music(a):
    for i in range(2):
        print 'I was listening to %s. %s' % (a,ctime())
        sleep(1)
def movie(b):
    for i in range(2):
        print 'I was watching to %s. %s' % (b,ctime())
        sleep(5)

# music('告白气球')
# movie('泰坦尼克号')
t1 = threading.Thread(target=music,args=('告白气球',))
t1.start()
t2 = threading.Thread(target=movie,args=('泰坦尼克号',))
t2.start()
print 'all over %s' %ctime()

这里写图片描述

4.线程锁

# _*_ coding:utf-8 _*_
"""
file:多进程_7.py
date:2018-07-25 8:21 AM
author:Jiong
desc:


"""
import threading
import time
num = 0

def run(n):
    time.sleep(1)
    global num
    # 线程锁
    lock.acquire()
    num += 1
    print '%s\n' %num
    lock.release()
lock = threading.Lock()
for i in range(150):
    t = threading.Thread(target=run,args=(i,))
    t.start()

这里写图片描述

5.异步

# _*_ coding:utf-8 _*_
"""
file:异步.py
date:2018-07-26 8:47 AM
author:Jiong
desc:


"""
import threading
import time

def Producer():
    print 'chef:等人来买包子'
    # 收到了消费者的event.set 也就是把这个flag改为了true,但是我们的包子并没有做好
    event.wait()
    # 此时应该将flag的值改回去
    event.clear()
    print 'chef:someone is coming for 包子'
    print 'chef:making a 包子 for someone'
    time.sleep(5)
    # 告诉人家包子做好了
    print '你的包子好了~'
    event.set()

def Consumer():
    print 'tom:去买包子'
    # 告诉人家我来了
    event.set()
    time.sleep(2)
    print 'tom:waiting for 包子 to be ready'
    # 我在不断检测,但我已经不阻塞了
    while True:
        if event.is_set():
            print 'Thanks~'
            break
        else:
            print '怎么还没好呀~'
            # 模拟正在做自己的事情
            time.sleep(1)
event = threading.Event()

p1 = threading.Thread(target=Producer)
c1 = threading.Thread(target=Consumer)
p1.start()
c1.start()

这里写图片描述

6.事件驱动

# _*_ coding:utf-8 _*_
"""
file:事件驱动.py
date:2018-07-26 8:48 AM
author:Jiong
desc:


"""
import threading
import time

def Producer():
    print 'chef:等人来买包子'
    #收到了消费者的event.set 也就是把这个flag改为了true,但是我们的包子并没有做好
    event.wait()
    #此时应该将flag的值改回去
    event.clear()
    print 'chef:someone is coming for 包子'
    print 'chef:making a 包子 for someone'
    time.sleep(5)
    # 告诉人家包子做好了
    print '你的包子好了~'
    event.set()

def Consumer():
    print 'tom:去买包子'
    # 告诉人家我来了
    event.set()
    time.sleep(2)
    print 'tom:waiting for 包子 to be ready'
    event.wait()
    print '哎呀~真好吃'

event = threading.Event()

p1 = threading.Thread(target=Producer)
c1 = threading.Thread(target=Consumer)
p1.start()
c1.start()

这里写图片描述

三·套接子(socket)

什么是socket

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket
所谓socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过“套接字”向网络发出请求或应答网络请求
socket起源于Uinx,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open–>读写write/read–>关闭close”模式来操作,socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写
IO,打开,关闭) Socket的英文原义是“孔”或“插座”。作为BSD
UNIX的进程通信机制,取后一种意思。通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。
客户软件将插头插到不同编号的插座,就可以得到不同的服务

例如:
中国移动客服 对于移动来说:一直监听一个号码10086,当有电话进来后,就分配一个客服和客户去沟通并处理请求
对于用户:需要知道10086这个号码,并需要打电话

1.建立服务端

# _*_ coding:utf-8 _*_
"""
file:服务端_server.py
date:2018-07-26 8:01 AM
author:Jiong
desc:


"""
import socket

# 1.创建socket对象
sk = socket.socket()
# 2.绑定端口和ip
ip_port = ('127.0.0.1', 9998)
sk.bind(ip_port)
# 3.最大连接数
sk.listen(5)

while True:
    # 获取客户端的ip和端口号
    conn, address = sk.accept()
    conn.send('hello')
    conn.close()

这里写图片描述

2.建立客户端

# _*_ coding:utf-8 _*_
"""
file:客户端_client.py
date:2018-07-26 8:02 AM
author:Jiong
desc:


"""
import socket

# 创建一个socket对象
client = socket.socket()

# 创建连接
ip_port = ('127.0.0.1',9998)
client.connect(ip_port)
# 获取数据
data = client.recv(1024)
print data

这里写图片描述

3.非交互式

让服务端一直运行,在终端调用python client.py
但是这种方式没有交互,只有单一的输出

[kiosk@foundation41 ~]$ ls
 PycharmProjects
[kiosk@foundation41 ~]$ cd PycharmProjects/
[kiosk@foundation41 PycharmProjects]$ ls
python
[kiosk@foundation41 PycharmProjects]$ cd python/
[kiosk@foundation41 python]$ ls
day08
[kiosk@foundation41 python]$ cd day08
[kiosk@foundation41 day08]$ ls
socket  
[kiosk@foundation41 day08]$ cd socket/
[kiosk@foundation41 socket]$ ls
客户端_client.py  
[kiosk@foundation41 socket]$ python 客户端_client.py 
hello
[kiosk@foundation41 socket]$ python 客户端_client.py 
hello

这里写图片描述

4.交互式(一问一答)

客户端_client

# _*_ coding:utf-8 _*_
"""
file:一问一答_client.py
date:2018-07-25 8:59 AM
author:Jiong
desc:


"""
import socket
# 创建一个socket对象
client = socket.socket()
# 创建连接
ip_port = ('127.0.0.1',9997)
client.connect(ip_port)

while True:
    # 获取数据
    data = client.recv(1024)
    print data
    # 发送数据
    inp = raw_input('client:')
    client.send(inp)
    if inp == 'exit':
        break

这里写图片描述
服务端_server

# _*_ coding:utf-8 _*_
"""
file:一问一答_server.py
date:2018-07-25 8:59 AM
author:Jiong
desc:


"""
import socket

# 1.创建socket对象
sk = socket.socket()
# 2.绑定端口和ip
ip_port = ('127.0.0.1', 9997)
sk.bind(ip_port)
# 3.最大连接数
sk.listen(5)

while True:
    # 获取客户端的ip和端口号
    conn, address = sk.accept()
    conn.send('hello')
    flag = True
    while flag:
        data = conn.recv(1024)
        print data
        if data == 'exit':
            flag = False
        conn.send('hi')
    conn.close()

这里写图片描述

这里写图片描述

猜你喜欢

转载自blog.csdn.net/Le_Anny/article/details/81219405