python - 我使用 django 连接池的多线程代码没有任何改进

标签 python django multithreading oracle11g connection-pooling

我正在努力使用 Django 上的连接池进行多线程处理。

我知道 python 线程存在 GIL 问题,但我认为如果大部分工作是 DB I/O,Python 线程足以提高性能。

首先我尝试实现一个小代码来证明我的想法。

简单地解释一下,代码使用 threadPool.apply_async() 以及由 settings.py 中的 CONN_MAX_AGE 设置的数据库连接池。

通过代码,我重复控制工作线程的线程数。

from multiprocessing            import pool
from threadPoolTestWithDB_IO    import models
from django.db                  import transaction
import django
import datetime
import logging
import g2sType


def addEgm(pre, id_):
    """
    @summary: This function only inserts a bundle of records tied by a foreign key 
    """
    try:
        with transaction.atomic():

            egmId = pre + "_" + str(id_)
            egm = models.G2sEgm(egmId=egmId, egmLocation="localhost")
            egm.save()

            device = models.Device(egm=egm,
                          deviceId=1,
                          deviceClass=g2sType.t_deviceClass.G2S_eventHandler,
                          deviceActive=True)
            device.save()

            models.EventHandlerProfile(device=device, queueBehavior="a").save()
            models.EventHandlerStatus(device=device).save()

            for i2 in range(1, 200):
                models.EventReportData(device=device,
                                       deviceClass=g2sType.t_deviceClass.G2S_communications,
                                       deviceId=1,
                                       eventCode="TEST",
                                       eventText="",
                                       eventId=i2,
                                       transactionId=0
                                       ).save()

            print "Done %d" % id_


    except Exception as e:
        logging.root.exception(e)


if __name__ == "__main__":

    django.setup()
    logging.basicConfig()

    print "Start test"

    tPool = pool.ThreadPool(processes=1)    #Set the number of processes

    s = datetime.datetime.now()
    for i in range(100):                    #Set the number of record bundles
        tPool.apply_async(func=addEgm, args=("a", i))

    print "Wait worker processes"
    tPool.close()                           
    tPool.join()

    e = datetime.datetime.now()
    print "End test"

    print "Time Measurement : %s" % (e-s,)

    models.G2sEgm.objects.all().delete()    #remove all records inserted while the test
--------------------------
# settings.py


DATABASES = {
             'default': {
                         'ENGINE': 'django.db.backends.oracle',
                         'NAME': 'orcl',
                         'USER': 'test',
                         'PASSWORD': '1123',
                         'HOST': '192.168.0.90',
                         'PORT': '1521',
                         'CONN_MAX_AGE': 100,
                         'OPTIONS': {'threaded': True}
                         }
             }

但是,结果是,1 线程工作和多线程工作之间没有太大区别。

例如,10 个线程需要 30.6 秒,1 个线程需要 30.4 秒

我做错了什么?

最佳答案

要么您在数据库级别遇到问题。您可以通过执行以下查询来证明这一点:

select /* +rule */
    s1.username || '@' || s1.machine
    || ' ( SID=' || s1.sid || ' ' || s1.program || ' )  is blocking ' || s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ' || s2.program || ' ) ' AS blocking_status
    from v$lock l1, v$session s1, v$lock l2, v$session s2
    where s1.sid=l1.sid and s2.sid=l2.sid
    and l1.BLOCK=1 and l2.request > 0
    and l1.id1 = l2.id1
    and l2.id2 = l2.id2 ;

或者Python中有线程被阻塞。 (可能在数据库驱动程序级别)。 将gdb附加到python进程,然后执行thread apply all bt

你会看到的。

关于python - 我使用 django 连接池的多线程代码没有任何改进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35037302/

相关文章:

python - 我如何通过 django session 中存储的属性来限制 django 外键选择

python - 将正则表达式转换为有限状态机

python - 如何在 python 中找到 numpy 矩阵的长度(或尺寸、大小)?

django - 如何仅为 django 管理门户设置默认 TZ?

django - 重置Django缓存模板加载器的缓存

c++ - windows C++ 多线程

c# - 简单的线程测试

c# - 将数据从多个线程发送回主线程的最佳方法是什么?

python - 寻找影响净收入的特征

python - 如何按列值的计数进行分组并对其进行排序?