简单连接池 vs 线程化连接池:什么是线程安全?

4

我正在尝试弄清楚psycopg2连接池中SimpleConnectionPoolThreadedConnectionPool之间的区别。

文档中提到:
SimpleConnectionPool 连接只能在单线程应用程序/脚本中使用。
ThreadedConnectionPool 连接可以在多线程应用程序/脚本中安全地使用。

这里的“安全”是什么意思?

我的理解/困惑:


"""
eg1: Simple Connection Pooling example
"""

from psycopg2.pool
from concurrent.futures

def someTask(id):
  # CRUD queries to Postgres, that I will be multithreading
  print(f"Thread: {id}")
  conn = simple_pool.getconn()
  # do DB operation


simple_pool = psycopg2.pool.SimpleConnectionPool(10, 15, #DB Info)

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
  executor.map(someTask, range(1,10))



"""
eg2: Threaded Connection Pooling example
"""

from psycopg2.pool
from concurrent.futures

def someTask(id):
  # CRUD queries to Postgres, that I will be multithreading
  print(f"Thread: {id}")
  conn = threaded_pool.getconn()
  # do DB operation


threaded_pool = psycopg2.pool.ThreadedConnectionPool(10, 15, #DB Info)

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
  executor.map(someTask, range(1,10))

Q1: 我可能理解有误,但在示例1中,someTask()函数将被每个线程调用,因此如果它是一个简单的连接池,这将产生错误/不安全(这是什么意思?)。

Q2: 在示例2中,如果示例正确,那么线程安全是什么意思,someTask()函数将允许从池中获取连接,在示例1中则不会?

Q3: 这两者之间是否有性能差异?

非常感谢您提供更多的资源/文章/文本以更好地理解这个问题。谢谢。

2个回答

3
根据SimpleConnectionPool文档,它被定义为:“一个无法在不同线程之间共享的连接池”。这证实了您在第一个问题中所说的。即使它在没有错误的情况下运行,在多个线程中同时使用SimpleConnectionPool可能会导致未定义的行为/错误结果,因为线程之间存在竞争条件。
至于第二个问题,线程安全意味着对象可以被多个线程同时使用,而无需处理竞争条件。如果按照ThreadedConnectionPool实现方式,您可以看到这种情况确实如此。他们使用锁来确保没有连接同时被两个线程共享。
我不能评论两者之间性能差异,因为它们有不同的用例。

0
Q1: 我可能理解有误,但是在例子1中,someTask()函数将会被每个线程调用,所以如果它是一个简单的连接池,这将导致错误/不安全(这是什么意思?)。
是的,someTask将在每个工作线程中被调用,并且使用ThreadPoolExecutor与SimpleConnectionPool并不是一个好主意,因为ThreadPoolExecutor是一个多线程执行器,会调用你的someTask函数。
所以例子1显然是线程不安全的,因为它使用线程作为设计的主要组成部分。
Q2: 而在例子2中,如果这个例子是正确的,那么THREAD SAFE表示someTask()函数将被允许从连接池中获取连接,而在例子1中则不行?
  • 本质上,这意味着您的每个工作进程都将知道如何与连接池相互协作。

  • 工作进程A不会开始使用连接池中的连接,只是被工作进程B打断。

  • 工作进程A、B、C等将以有序和“友好”的方式与连接池进行接口交互,如果需要,它们将等待自己的轮次。

Q3:两者之间是否有性能差异?

  • 是的,根据您所寻找的内容,例如1肯定行不通。
  • 例如2,利用线程安全的连接池进行线程处理,其工作进程可以同时工作,而单线程解决方案则需要更长的时间。

如果正确实现了两种解决方案,它们都将具有高性能,单线程和多线程方法之间唯一的区别在于时间和任何给定时刻消耗的资源。

我希望这有助于澄清问题,还请查看关于此主题的这些文章,herehere


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接