python_07_mysql,多线程,socket

本文详细介绍了Python中与MySQL交互的MySQLdb模块,包括安装、数据库连接与操作。接着讨论了多线程的使用,特别是threading模块的线程类和线程安全。最后探讨了Socket编程的基础知识及其在服务器与客户端通信中的应用。
摘要由CSDN通过智能技术生成

1.mysql

1)什么是MySQLdb?
MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的
2)安装部署MySQL-Python
打开shell执行pip install MySQL-Python 或 yum install MySQL-python
为了用DB-API编写MySQL脚本,必须确保已经安装了MySQL。复制以下代码,并执行:

import MySQLdb

如果执行后的输出结果如下所示,意味着你没有安装 MySQLdb 模块:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    import MySQLdb
ImportError: No module named MySQLdb

3)数据库连接

连接数据库前,请先确认以下事项:

您已经创建了数据库python.
在python数据库中您已经创建了表message
message表字段为name和money
连接数据库python使用的用户名为"root" ,密码为 "redhat",你可以可以自己设定或者直接使用root用户名及其密码
在你的主机上已经安装了 Python MySQLdb 模块

4)数据库中字段信息管理
增加字段:insert

import MySQLdb
# 打开数据库连接
conn = MySQLdb.connect(host='localhost', user='root', passwd='redhat', db='python')
# 使用cur()方法获取操作游标
cur = conn.cursor()
# 创建数据表SQL语句增加字段信息
sql = 'insert into message(money,name) values(%s,%s)'
params = ('2', 'tom',)
# 使用execute方法执行SQL语句
recount = cur.execute(sql,params)
# 提交信息
conn.commit()
cur.close()
# 关闭数据库连接
conn.close()

执行:
这里写图片描述
这里写图片描述
结果:
这里写图片描述
删除字段:delete

import MySQLdb
# 打开数据库连接
conn = MySQLdb.connect(host='localhost',user='root',passwd='redhat',db='python')
# 使用cur()方法获取操作游标
cur = conn.cursor()
# 创建数据表SQL语句删除字段信息
sql = 'delete from message where name = %s'
params = ('lily',)
# 使用execute方法执行SQL语句
recount = cur.execute(sql,params)
# 提交信息
conn.commit()

cur.close()
# 关闭数据库连接
conn.close()

执行
这里写图片描述
结果:
这里写图片描述
更改字段:update

import MySQLdb
# 打开数据库连接
conn =  MySQLdb.Connect(host='localhost',user='root',passwd='redhat',db='python')
# 使用cur()方法获取操作游标
cur = conn.cursor()
# 创建数据表SQL语句更改字段信息
sql = 'update message set money = %s where name = %s'
params = (50,'lin')
# 使用execute方法执行SQL语句
recount = cur.execute(sql,params)
# 提交信息
conn.commit()
cur.close()
# 关闭数据库连接
conn.close()

zhixing
这里写图片描述
结果:
这里写图片描述
查询字段:select

import MySQLdb
# 打开数据库连接
conn = MySQLdb.connect(host='localhost',user='root',passwd='redhat',db='python')
# 使用cur()方法获取操作游标
cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
# 使用execute方法执行SQL语句
recont = cur.execute('select * from message')
data = cur.fetchall()
cur.close()
# 关闭数据库连接
conn.close()
print data

执行结果:
这里写图片描述
3)回滚
执行多个操作时,当其中一个出现错误,其他也不会执行
例如:将lily的钱转给lin

import MySQLdb
# 打开数据库连接
conn = MySQLdb.connect(host='localhost',user='root',passwd='redhat',db='python')
# 使用cur()方法获取操作游标
cur = conn.cursor()
# 创建数据表SQL语句更改字段信息
sql = 'update message set money = %s where name = %s'
params1 = (0,'lily')
# 使用execute方法执行SQL语句
recount = cur.execute(sql,params1)

sql = 'update message set money = %s where name = %s'
params2 = (150,'lin')
recount2 = cur.execute(sql,params2)
# 提交信息
conn.commit()

cur.close()
# 关闭数据库连接
conn.close()

建立lily和lin两个字段
这里写图片描述
执行:
这里写图片描述
执行结果:
这里写图片描述
如果第二个出错
这里写图片描述
则两个都不会执行
这里写图片描述

2.多线程—threading

threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。python当前版本的多线程库没有实现优先级、线程组,线程也不能被停止、暂停、恢复、中断。

threading模块提供的类
  Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。
threading 模块提供的常用方法
  threading.currentThread(): 返回当前的线程变量。
  threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  threading.activeCount():返回正在运行的线程数量,
  与len(threading.enumerate())有相同的结果。
threading 模块提供的常量
  threading.TIMEOUT_MAX 设置threading全局超时时间。
1)Thread类
Thread是线程类,有两种使用方法,直接传入要运行的方法或从Thread继承并覆盖run():
构造方法
Thread(group=None, target=None, name=None, args=(), kwargs={})

  group: 线程组,目前还没有实现,库引用中提示必须是None;
  target: 要执行的方法;
  name: 线程名;
  args/kwargs: 要传入方法的参数。
实例方法
  isAlive(): 返回线程是否在运行。正在运行指启动后、终止前。
  get/setName(name): 获取/设置线程名。
  start(): 线程准备就绪,等待CPU调度
  is/setDaemon(bool): 获取/设置是后台线程(默认前台线程(False)),(在start之前设置)
  如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,主线程和后台线程均停止
  如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
  start(): 启动线程。
  join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)
示例1:getName()

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'

执行结果:
这里写图片描述
示例2:setDaemon(bool)

import time
from threading import Thread
def Foo():
    for i in range(20):
        print i
        time.sleep(1)
print 'before'
t1 = Thread(target=Foo)
t1.setDaemon(True)
t1.start()
print 'after'
time.sleep(10)

执行结果:
这里写图片描述
示例3:jion([timeout])

import time
from threading import Thread
def Foo():
    for i in range(10):
        print i
        time.sleep(1)

print 'before'
t1 = Thread(target=Foo)
t1.start()
t1.join(2)
print 'after'

执行结果:
这里写图片描述
示例4
如果不使用多线程:第一个函数执行完才会执行第二个函数
例如:

from threading import Thread
from time import ctime,sleep
def music(a):
    for i in range(2):
        print '我在听%s.%s'%(a,ctime())
        sleep(2)

def movie(b):
    for i in range(2):
        print '我在看%s.%s'%(b,ctime())
        sleep(3)

music('告白气球')
movie('战狼2')

执行结果:
这里写图片描述
使用多线程:

from threading import Thread
from time import ctime,sleep
def music(a):
    for i in range(2):
        print '我在听%s.%s'%(a,ctime())
        sleep(2)

def movie(b):
    for i in range(2):
        print '我在看%s.%s'%(b,ctime())
        sleep(3)
t1 = Thread(target=music,args=('告白气球',))
t1.start()
t2 = Thread(target=movie,args=('战狼2',))
t2.start()

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

import threading
import time
import Queue
import random
def producer(name,que):
    while True:
        if que.qsize() <3:
            que.put('baozi')
            print '%s:made a baozi'% name
        else:
            print '还有三个包子'
        time.sleep(random.randrange(5))
def consumer(name,que):
    while True:
        try:
            que.get_nowait()
            print '%s:got a baozi' % name
        except Exception:
            print '没有包子了'
        time.sleep(random.randrange(3))

q = Queue.Queue()

p1 = threading.Thread(target=producer,args=['chef1',q])
p2 = threading.Thread(target=producer,args=['chef2',q])
p1.start()
p2.start()

c1 = threading.Thread(target=consumer,args=['tom',q])
c2 = threading.Thread(target=consumer,args=['harry',q])
c1.start()
c2.start()

执行结果:
这里写图片描述
事件驱动:

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()

执行结果:
这里写图片描述
异步:

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()

执行结果:
这里写图片描述
3)Lock类
  由于线程之间随机调度:某线程可能在执行n条后,CPU接着执行其他线程。为了多个线程同时操作一个内存中的资源时不产生混乱,我们使用锁。

Lock(指令锁)是可用的最低级的同步指令。Lock处于锁定状态时,不被特定的线程拥有。Lock包含两种状态——锁定和非锁定,以及两个基本的方法。

可以认为Lock有一个锁定池,当线程请求锁定时,将线程至于池中,直到获得锁定后出池。池中的线程处于状态图中的同步阻塞状态。

RLock(可重入锁)是一个可以被同一个线程请求多次的同步指令。RLock使用了“拥有的线程”和“递归等级”的概念,处于锁定状态时,RLock被某个线程拥有。拥有RLock的线程可以再次调用acquire(),释放锁时需要调用release()相同次数。

可以认为RLock包含一个锁定池和一个初始值为0的计数器,每次成功调用 acquire()/release(),计数器将+1/-1,为0时锁处于未锁定状态。

简言之:Lock属于全局,Rlock属于线程。

构造方法
Lock(),Rlock(),推荐使用Rlock()

实例方法
  acquire([timeout]): 尝试获得锁定。使线程进入同步阻塞状态。
  release(): 释放锁。使用前线程必须已获得锁定,否则将抛出异常。
例:
不加线程锁

import threading
import time
num =0
def run(n):
    time.sleep(1)
    global num
    num += 1
    print '%s\n' % num
for i in range(100):
    t = threading.Thread(target=run,args=(i,))
    t.start()

执行结果:
这里写图片描述
加线程锁:

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(100):
    t = threading.Thread(target=run,args=(i,))
    t.start()

执行结果:
这里写图片描述

3.socket

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

基本上,Socket 是任何一种计算机网络通讯中最基础的内容。例如当你在浏览器地址栏中输入http://www.cnblogs.com/时,你会打开一个套接字,然后连接到 http://www.cnblogs.com/并读取响应的页面然后然后显示出来。而其他一些聊天客户端如 gtalk 和 skype 也是类似。任何网络通讯都是通过 Socket 来完成的。

Python 官方关于 Socket 的函数请看 http://docs.python.org/library/socket.html

socket和file的区别:

  1、file模块是针对某个指定文件进行【打开】【读写】【关闭】

  2、socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】
这里写图片描述
服务端:

import socket
# 创建socket对象
sk = socket.socket()
ip_port = ('127.0.0.1',6663)
sk.bind(ip_port)
sk.listen(5)
while True:
    conn,address = sk.accept()
    conn.send('hello')
    flag = True
    while flag:
        data = conn.recv(1024)
        print data
        if data == 'exit':
            flag = False
        conn.send('sb')
    conn.close()

客户端:

import socket

client = socket.socket()

ip_port = ('127.0.0.1',6663)
client.connect(ip_port)

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

    inp = raw_input('client:')
    client.send(inp)
    if  inp == 'exit':
        break

执行server.py:
这里写图片描述
打开shell执行client.py文件
这里写图片描述
执行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值