Coldfusion限制为总线程数

时间:2012-09-17 13:24:38

标签: multithreading coldfusion cfhttp

我有一些代码试图创建100个线程的http调用。它似乎被限制在40左右。

当我执行threadJoin时,我只能从我的http调用获得38到40组结果,尽管循环是从1到100。

// thread http calls
pages = 100;

for (page="1";page <= pages; page++) {

    thread name="req#page#" {

        grabber.setURL('http://site.com/search.htm');
        // request headers
        grabber.addParam(type="url",name="page",value="#page#");
        results = grabber.send().getPrefix();

        arrayAppend(VARIABLES.arrResults,results.fileContent);
    }
}

// rejoin threads
for (page="2";page <= pages; page++) {
    threadJoin('req#page#',10000);
}

CF可以创建的线程数有限制吗?是否与在后台运行的Java有关?或者它不能处理那么多的http请求吗?

除了线程HTTP调用之外,还有一个更好的方法吗?

2 个答案:

答案 0 :(得分:6)

您看到的结果可能是因为您的变量不是线程安全的。

grabber.addParam(type="url",name="page",value="#page#");

该行正在访问由所有衍生线程共享的Variables.Page。由于线程在不同的时间开始,page的值通常与您认为的值不同。这将导致多个线程具有page的相同值。

相反,如果将page作为属性传递给线程,那么每个线程将拥有自己的变量版本,最终将得到100个唯一值。 (1-100)。

此外,您还要写一个共享变量。

arrayAppend(VARIABLES.arrResults,results.fileContent);

ArrayAppend不是线程安全的,你将用其他版本的自身覆盖VARIABLES.arrResults的版本,而不是附加每个位。

您希望将结果设置为thread变量,然后在连接完成后访问该变量。

thread name="req#page#" page=Variables.page {

    grabber.setURL('http://site.com/search.htm');
    // request headers
    grabber.addParam(type="url",name="page",value="#Attributes.page#");
    results = grabber.send().getPrefix();

    thread.Result = results.fileContent;
}

加入:

// rejoin threads
for (page="2";page <= pages; page++) {
    threadJoin('req#page#',10000);
    arrayAppend(VARIABLES.arrResults, CFThread['req#page#'].Result);
}

答案 1 :(得分:3)

在ColdFusion管理员中,有一个设置可以同时运行多少个,我的默认为10.其余的显然是排队的。一个Phantom42提到,你可以增加运行CF线程的数量,但是,如果有100个或更多线程,你可能会遇到其他问题。

在32位进程上,整个进程只能使用2gig的内存。每个线程占用一定量的堆栈内存,这不是堆的一部分。由于Java Binary + Heap + Non-Heap(PermGen)+(线程* 512k)可以轻松超过2-gig限制,因此我们遇到了大量线程内存不足的问题。

你还必须允许足够的线程来处理上面的代码,以及进入你的应用程序的其他请求,这可能会使整个应用程序陷入困境。

我建议更改代码以创建N个线程,每个线程执行多个请求。这是更多的工作,但你打破了N requests = N Threads问题。您可以采取以下几种方法:

  • 如果您认为每个请求大致需要大约相同的时间,那么您可以分开工作并为每个线程分配一部分工作,然后再启动每个请求。

  • 或者每个线程从列表中选择一个URL并对其进行处理,然后您可以加入所有N个线程。您需要确保将锁定放在用于跟踪进度的任何计数器周围。