J'ai un programme multi-threadé en Python qui parle avec une base
Postgres. Pour éviter les problèmes d'accès concurrentiels avec la base,
je crée un thread qui va recevoir les requêtes des autres threads via
queue.get et queue.put (il ne fait que des insert, donc je n'ai pas
besoin de vérifier la valeur de retour de la requete).
Mon problème est que si je limite à 10 threads, no problems, tout
fonctionne.
Mais si je monte à 100 threads, le programme se bloque (visiblement sur
lock_acquire()).
Tous les put() et get() sont avec True et un timeout de 5 secondes.
Avant de rentrer dans le détail du code, y-a-t-il quelque chose
d'évident que je ne sais pas ? genre faire 100 threads avec Python, je
suis en pleine science fiction ou le global lock est incapable de gérer
plus de 15 threads correctement ?
La fonction du thread qui gère les requetes SQL
def execute_sql(q):
print("Start SQL Thread")
while True:
try:
data = q.get(True,5)
except:
print("No data")
continue
print("RECEIVED SQL ORDER")
print(data)
print("END")
if data == "EXIT":
return
try:
request = data['request']
arg = data['arg']
ref.execute(request,arg)
except:
print("Can not execute SQL request")
print(data)
L'appel de ce thread depuis un autre thread
sql = dict()
sql['request'] = "update b2_user set credit = credit -%s where id = %s"
sql['arg'] = (i,username,)
try:
q.put(sql,True,5)
except:
print("Can not insert data")
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Artis Sideley
On Thursday, 14 May 2020 11:24:26 UTC+2, Stephane Tougard wrote:
Bonjour, J'ai un programme multi-threadé en Python qui parle avec une base Postgres. Pour éviter les problèmes d'accès concurrentiels avec la base, je crée un thread qui va recevoir les requêtes des autres threa ds via queue.get et queue.put (il ne fait que des insert, donc je n'ai pas besoin de vérifier la valeur de retour de la requete). Mon problème est que si je limite à 10 threads, no problems, to ut fonctionne. Mais si je monte à 100 threads, le programme se bloque (visiblement sur lock_acquire()). Tous les put() et get() sont avec True et un timeout de 5 secondes. Avant de rentrer dans le détail du code, y-a-t-il quelque chose d'évident que je ne sais pas ? genre faire 100 threads avec Python, je suis en pleine science fiction ou le global lock est incapable de gé rer plus de 15 threads correctement ? La fonction du thread qui gère les requetes SQL def execute_sql(q): print("Start SQL Thread") while True: try: data = q.get(True,5) except: print("No data") continue print("RECEIVED SQL ORDER") print(data) print("END") if data == "EXIT": return try: request = data['request'] arg = data['arg'] ref.execute(request,arg) except: print("Can not execute SQL request") print(data) L'appel de ce thread depuis un autre thread sql = dict() sql['request'] = "update b2_user set credit = credit -%s where id = %s" sql['arg'] = (i,username,) try: q.put(sql,True,5) except: print("Can not insert data") Et le lancement du thread SQL q = qu.Queue() t = th.Thread(target = execute_sql, args = (q,)) t.start()
Normalement, les SGBD ont intrinsèquement des mécanismes de prote ction contre les pb d'accès concurrents. Mais si vous avez besoin d'or donner les requetes, programmer les requetes séquentiellement dans un unique thread. Le multi thread est consommateur de ressources mémoire. Dans votre cas , s'il ne s'agit d'émettre les requetes et recevoir les résultats , essayer la bibliothèque 'asyncio' beaucoup plus économe en ress ources.
On Thursday, 14 May 2020 11:24:26 UTC+2, Stephane Tougard wrote:
Bonjour,
J'ai un programme multi-threadé en Python qui parle avec une base
Postgres. Pour éviter les problèmes d'accès concurrentiels avec la base,
je crée un thread qui va recevoir les requêtes des autres threa ds via
queue.get et queue.put (il ne fait que des insert, donc je n'ai pas
besoin de vérifier la valeur de retour de la requete).
Mon problème est que si je limite à 10 threads, no problems, to ut
fonctionne.
Mais si je monte à 100 threads, le programme se bloque (visiblement sur
lock_acquire()).
Tous les put() et get() sont avec True et un timeout de 5 secondes.
Avant de rentrer dans le détail du code, y-a-t-il quelque chose
d'évident que je ne sais pas ? genre faire 100 threads avec Python, je
suis en pleine science fiction ou le global lock est incapable de gé rer
plus de 15 threads correctement ?
La fonction du thread qui gère les requetes SQL
def execute_sql(q):
print("Start SQL Thread")
while True:
try:
data = q.get(True,5)
except:
print("No data")
continue
print("RECEIVED SQL ORDER")
print(data)
print("END")
if data == "EXIT":
return
try:
request = data['request']
arg = data['arg']
ref.execute(request,arg)
except:
print("Can not execute SQL request")
print(data)
L'appel de ce thread depuis un autre thread
sql = dict()
sql['request'] = "update b2_user set credit = credit -%s where id = %s"
sql['arg'] = (i,username,)
try:
q.put(sql,True,5)
except:
print("Can not insert data")
Normalement, les SGBD ont intrinsèquement des mécanismes de prote ction contre les pb d'accès concurrents. Mais si vous avez besoin d'or donner les requetes, programmer les requetes séquentiellement dans un unique thread.
Le multi thread est consommateur de ressources mémoire. Dans votre cas , s'il ne s'agit d'émettre les requetes et recevoir les résultats , essayer la bibliothèque 'asyncio' beaucoup plus économe en ress ources.
On Thursday, 14 May 2020 11:24:26 UTC+2, Stephane Tougard wrote:
Bonjour, J'ai un programme multi-threadé en Python qui parle avec une base Postgres. Pour éviter les problèmes d'accès concurrentiels avec la base, je crée un thread qui va recevoir les requêtes des autres threa ds via queue.get et queue.put (il ne fait que des insert, donc je n'ai pas besoin de vérifier la valeur de retour de la requete). Mon problème est que si je limite à 10 threads, no problems, to ut fonctionne. Mais si je monte à 100 threads, le programme se bloque (visiblement sur lock_acquire()). Tous les put() et get() sont avec True et un timeout de 5 secondes. Avant de rentrer dans le détail du code, y-a-t-il quelque chose d'évident que je ne sais pas ? genre faire 100 threads avec Python, je suis en pleine science fiction ou le global lock est incapable de gé rer plus de 15 threads correctement ? La fonction du thread qui gère les requetes SQL def execute_sql(q): print("Start SQL Thread") while True: try: data = q.get(True,5) except: print("No data") continue print("RECEIVED SQL ORDER") print(data) print("END") if data == "EXIT": return try: request = data['request'] arg = data['arg'] ref.execute(request,arg) except: print("Can not execute SQL request") print(data) L'appel de ce thread depuis un autre thread sql = dict() sql['request'] = "update b2_user set credit = credit -%s where id = %s" sql['arg'] = (i,username,) try: q.put(sql,True,5) except: print("Can not insert data") Et le lancement du thread SQL q = qu.Queue() t = th.Thread(target = execute_sql, args = (q,)) t.start()
Normalement, les SGBD ont intrinsèquement des mécanismes de prote ction contre les pb d'accès concurrents. Mais si vous avez besoin d'or donner les requetes, programmer les requetes séquentiellement dans un unique thread. Le multi thread est consommateur de ressources mémoire. Dans votre cas , s'il ne s'agit d'émettre les requetes et recevoir les résultats , essayer la bibliothèque 'asyncio' beaucoup plus économe en ress ources.