python多线程学

import csv
import threading
import queue
import time
from concurrent.futures import ThreadPoolExecutor, as_completed,wait
from dbutils.persistent_db import PersistentDB
import sqlite3
 
 
class Pool(object):       # 数据库连接池
    __pool = None     # 记录第一个被创建的对象引用
    config = {
        'database': 'lac_ci.db'  # 数据库文件路径
    }
 
    def __new__(cls, *args, **kwargs):
        """创建连接池对象  单例设计模式(每个线程中只创建一个连接池对象)  PersistentDB为每个线程提供专用的连接池"""
        if cls.__pool is None:    # 如果__pool为空,说明创建的是第一个连接池对象
            cls.__pool = PersistentDB(sqlite3, maxusage=None, closeable=False, **cls.config)
        return cls.__pool
 
 
class Connect:
    def __enter__(self):
        """自动从连接池中取出一个连接"""
        db_pool = Pool()
        self.conn = db_pool.connection()
        self.cur = self.conn.cursor()
        return self
 
    def __exit__(self, exc_type, exc_val, exc_tb):
        """自动释放当前连接资源 归还给连接池"""
        self.cur.close()
        self.conn.close()
 

 
 
"""
SQLite 由于线程安全机制 不支持 PooledDB 线程共享连接模式   故使用PersistentDB 线程专用连接模式 为每个线程单独开连接池
SQLite 只支持读并发 即:写独占,读共享,所以要在修改操作时使用互斥锁。 为了体现精简性,这里就不演示了
PooledDB()中的参数解释自行查找
"""
# 定义一个队列,用于在读取线程和写入线程之间传递数据
data_queue = queue.Queue()
mutex = threading.Lock()
reader = None

# 创建数据库连接池
pool = None

# 定义一个函数,用于处理每一行数据
def process_row():
    
    while True:
    
        mutex.acquire()
        row = next(reader, "end")
        mutex.release()
        
     
        if(row == "end"):
            break;

        # 获取第四列的数值并加一
        lac = int(row[0])
        ci = int(row[1])

        # 查询数据库是否已经存在
        with Connect() as conn:
            cursor = conn.cur.execute("SELECT lon,lat,radius FROM LacCiT WHERE lac = ? AND ci = ?",(lac, ci))
            result = cursor.fetchone()
        
        if(result != None): 
            lat = result[0]
            lon = result[1]
            radius = result[2]
            # 将结果写入
            row.extend([str(lon),str(lat),str(radius)])
        else:
            pass
        
        
        # 将处理后的行放入队列
        data_queue.put(row)

# 定义一个函数,用于写入数据到CSV文件
def write_csv(filename):
    with open(filename, 'w', newline='') as file:
        writer = csv.writer(file)
        while True:
            try:
                # 从队列中获取处理后的行并写入文件
                row = data_queue.get(timeout=1)  # 设置超时以避免无限等待
                writer.writerow(row)
                data_queue.task_done()
            except queue.Empty:
                # 队列为空,说明数据已经全部处理完毕
                break


if __name__ == "__main__":
    # 指定你的CSV文件路径
    csv_file = 'lac_tt.csv'
    start_time = time.time()  # 记录程序开始时间
    
    obj_list = []
    file = open(csv_file, 'r', newline='')
    reader = csv.reader(file)
    
    with ThreadPoolExecutor(max_workers=10) as executor:
        executor.submit(process_row)
        executor.submit(process_row)
        executor.submit(process_row)
            
    write_csv('new_file.csv')

    print("CSV文件处理完成。")
    end_time = time.time()  # 记录程序结束时间
    
    elapsed_time = end_time - start_time  # 计算运行时间
    print(f"程序运行时间:{elapsed_time:.2f} 秒")

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值