Java essay Java essay
首页
  • Java基础
  • Java进阶
  • 设计模式
  • 多线程
  • Java你不知道的小事
  • Spring初识
  • Spring进阶
  • SpringBoot基础
  • SpringBoot进阶
  • 什么是微服务
  • SpringCloud全家桶
  • Dubbo
  • SpringCloud Alibaba
  • Vue
  • 小程序
  • 博客搭建
  • 数据库
  • python
  • 大数据
  • 性能分析优化
  • 中间件
  • 云原生
  • 面试
  • 外卖霸王餐
  • 打工人的带饭生活
  • 30岁我该怎么办
友链
关于我
GitHub (opens new window)

Mr.Fire

全栈工程师
首页
  • Java基础
  • Java进阶
  • 设计模式
  • 多线程
  • Java你不知道的小事
  • Spring初识
  • Spring进阶
  • SpringBoot基础
  • SpringBoot进阶
  • 什么是微服务
  • SpringCloud全家桶
  • Dubbo
  • SpringCloud Alibaba
  • Vue
  • 小程序
  • 博客搭建
  • 数据库
  • python
  • 大数据
  • 性能分析优化
  • 中间件
  • 云原生
  • 面试
  • 外卖霸王餐
  • 打工人的带饭生活
  • 30岁我该怎么办
友链
关于我
GitHub (opens new window)
  • python基础
  • python面向对象
  • python进阶
    • 1. Python 操作数据库
      • 1.1 python操作MySQL
      • 1.2 执行事务
      • 1.3 python操作Mysql的其他方式
    • 2. Python 多进程
    • 3. Python 多线程
      • 3.1 线程模块
      • 3.1.1 使用Threading模块创建线程
      • 3.2 线程同步
      • 3.2.1 Lock和RLock
      • 3.2.2 Condition
      • 3.2.3 ThreadLocal
      • 3.2.4 线程优先级队列
  • Python
Mr.Fire
2024-09-26
目录

python进阶

  • 1. Python 操作数据库
    • 1.1 python操作MySQL
    • 1.2 执行事务
    • 1.3 python操作Mysql的其他方式
  • 2. Python 多进程
  • 3. Python 多线程
    • 3.1 线程模块
    • 3.2 线程同步

# 1. Python 操作数据库

Python操作数据库可以使用标准数据库接口Python DB-API,或者是使用第三方库,如mysql-connector,PyMySQL、SQLAlchemy等。

Python的DB-API,为大多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库。

Python DB-API使用流程:

  • 引入 API 模块。
  • 获取与数据库的连接。
  • 执行SQL语句和存储过程。
  • 关闭数据库连接。

# 1.1 python操作MySQL

前提:安装MySQLdb,安装数据库

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import MySQLdb

# 打开数据库连接
db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# 使用execute方法执行SQL语句
cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法获取一条数据
data = cursor.fetchone()

print "Database version : %s " % data

# 关闭数据库连接
db.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 1.2 执行事务

  1. 原子性(atomicity): 一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
  2. 一致性(consistency): 事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
  3. 隔离性(isolation): 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性(durability): 持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
# SQL删除记录语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 向数据库提交
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

1
2
3
4
5
6
7
8
9
10
11

# 1.3 python操作Mysql的其他方式

python连接mysql数据库的三种方式参考: https://www.voycn.com/article/pythonlianjiemysqlshujukudesanzhongfangshimysqlconnector-pymysql-mysqldb (opens new window)

# 2. Python 多进程

Python的multiprocessing模块支持多进程,multiprocessing模块提供了一个Process类来代表一个进程对象。 Process类的方法和Thread类的方法类似,例如,start()方法用于启动进程,join()方法可以等待子进程结束后再继续往下运行,terminate()方法用于终止子进程。Process类的构造方法如下:

class multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={})
1
  • group: 线程组,目前还没有实现,传None即可
  • target: 如果不为None,则子进程启动时将运行这个对象
  • name: 子进程的名称
  • args: 传递给target函数的位置参数,元组形式
  • kwargs: 传递给target函数的字典参数
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import multiprocessing
import time
def worker(num):
    print 'Worker:', num
    time.sleep(2)
    print 'end'
if __name__ == '__main__':
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        jobs.append(p)
        p.start()
1
2
3
4
5
6
7
8
9
10
11
12
13
14

执行结果:

Worker: 0
Worker: 1
Worker: 2
Worker: 3
Worker: 4
end
end
end
end
end
1
2
3
4
5
6
7
8
9
10

# 3. Python 多线程

Python中使用线程有两种方式:函数或者用类来包装线程对象。

thread.start_new_thread ( function, args[, kwargs] )

1
2
  • function - 线程函数。
  • args - 传递给线程函数的参数,他必须是个tuple类型。
  • kwargs - 可选参数。

# 3.1 线程模块

Python通过两个标准库thread和threading提供对线程的支持。thread提供了低级别的、原始的线程以及一个简单的锁。

threading 模块提供的其他方法:

  • threading.currentThread(): 返回当前的线程变量。

  • threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

  • threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

  • 除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:

  • run(): 用以表示线程活动的方法。

  • start():启动线程活动。

  • join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。

  • isAlive(): 返回线程是否活动的。

  • getName(): 返回线程名。

  • setName(): 设置线程名。

# 3.1.1 使用Threading模块创建线程

#!/usr/bin/python
# -*- coding: UTF-8 -*-
       
import threading
import time
# 新线程执行的函数
def loop():
    print 'thread %s is running...' % threading.current_thread().name
    n = 0
    while n < 5:
        n = n + 1
        print 'thread %s >>> %s' % (threading.current_thread().name, n)
        time.sleep(1)
    print 'thread %s ended.' % threading.current_thread().name

print 'thread %s is running...' % threading.current_thread().name
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print 'thread %s ended.' % threading.current_thread().name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

执行结果:

thread MainThread is running...
thread LoopThread is running...
thread LoopThread >>> 1
thread LoopThread >>> 2
thread LoopThread >>> 3
thread LoopThread >>> 4
thread LoopThread >>> 5
thread LoopThread ended.
thread MainThread ended.
1
2
3
4
5
6
7
8
9

# 3.2 线程同步

线程同步就是当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作,而这段代码就是保证两个线程安全执行的关键。

# 3.2.1 Lock和RLock

  • Lock(指令锁)是互斥锁的基本实现,互斥锁保证了某段关键代码在某一时刻只能被一个线程执行,不能被多个线程同时执行。互斥锁使用acquire方法来获得锁,release方法来释放锁。
  • RLock(可重入锁)是Lock的子类,RLock内部维护着一个Lock和一个counter变量,counter记录了acquire,RLock的次数,没acquire一次,counter就加1,每次调用release将counter减1,直到counter为0,锁才被释放。RLock比Lock多了一个acquire和release方法,在同一个线程中,acquire和release可以嵌套使用,例如:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
lock = threading.RLock()
def func():
    lock.acquire()
    lock.acquire()
    print threading.currentThread().getName() + ' get lock'
    lock.release()
    lock.release()
t1 = threading.Thread(target=func)
t2 = threading.Thread(target=func)
t3 = threading.Thread(target=func)
t1.start()
t2.start()
t3.start()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

执行结果:

Thread-1 get lock
Thread-2 get lock
Thread-3 get lock
1
2
3

# 3.2.2 Condition

Condition和Lock类似,也支持acquire和release方法。Condition也支持wait和notify方法,但是Condition类中的这些方法比Lock类中的这些方法更复杂。

由于Condition类的这些方法涉及到线程间通信,所以比Lock类的这些方法更难理解。Condition的典型应用场景是生产者-消费者模型,生产者线程向队列中添加元素,消费者线程从队列中取出元素,如果队列为空,消费者线程等待,生产者线程添加元素后,唤醒消费者线程。

  • acquire([timeout]): 获得Condition内部的Lock。
  • release(): 释放Condition内部的Lock。
  • wait([timeout]): 调用这个方法将使当前线程进入Condition的等待队列,并释放Condition内部的Lock。当前线程被唤醒(或超时)后,将重新竞争Condition内部的Lock。Condition支持使用notify方法唤醒等待队列中的一个线程(选择由线程调度器决定),或使用notifyAll方法唤醒等待队列中的所有线程。
  • notify(): 唤醒等待队列中的一个线程。notifyAll(): 唤醒等待队列中的所有线程。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
import time
class MyThread(threading.Thread):
    def __init__(self, cond, name):
         threading.Thread.__init__(self)
         self.cond = cond
         self.name = name
     def run(self):
         self.cond.acquire()
         print '%s acquire lock' % self.name
         self.cond.wait()
         print '%s release lock' % self.name
         self.cond.release()
cond = threading.Condition()
t1 = MyThread(cond, 't1')
t2 = MyThread(cond, 't2')
t1.start()
t2.start()
time.sleep(1)
print 'Notify one'
cond.acquire()
cond.notify()
cond.release()

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

执行结果:

t1 acquire lock
t2 acquire lock
Notify one
t1 release lock
t2 wait
1
2
3
4
5

# 3.2.3 ThreadLocal

Python提供了ThreadLocal对象来实现线程间的数据隔离,ThreadLocal类表示线程本地数据,可以把TreadLocal类理解成全局变量,但是每个线程对该变量的操作(读写)都是线程隔离的,互相之间不会影响。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
# 创建全局ThreadLocal对象:
local_school = threading.local()
def process_student():
    # 获取当前线程关联的student:
    std = local_school.student
    print 'Hello, %s (in %s)' % (std, threading.current_thread().name)
def process_thread(name):
    # 绑定ThreadLocal的student:
    local_school.student = name
    process_student()
t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

执行结果:

Hello, Alice (in Thread-A)
Hello, Bob (in Thread-B)
1
2

# 3.2.4 线程优先级队列

Python的Queue模块提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading
import queue
import time
class MyThread(threading.Thread):
    def __init__(self, queue):
         threading.Thread.__init__(self)
         self.queue = queue
     def run(self):
         while True:
             item = self.queue.get()
             if item is None:
                 break
             print threading.current_thread().name, item
             self.queue.task_done()
q = queue.Queue()
threads = []
for i in range(5):
     t = MyThread(q)
     t.setDaemon(True)
     t.start()
     threads.append(t)
for item in range(10):
     q.put(item)
q.join()
for i in range(5):
     q.put(None)
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

执行结果:

Thread-1 0
Thread-2 1
Thread-3 2
Thread-4 3
Thread-5 4
Thread-1 5
Thread-2 6
Thread-3 7
Thread-4 8
Thread-5 9
1
2
3
4
5
6
7
8
9
10
最后更新时间: 2025/01/02, 15:50:35
python面向对象

← python面向对象

最近更新
01
SuperBuilder
12-29
02
30岁我该怎么办
12-29
03
关于存钱
12-29
更多文章>
Theme by Vdoing | Copyright © 2021-2025 Mr.Fire | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式