4

我有一些代码试图创建 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 调用更好的方法吗?

4

3 回答 3

7

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

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);
}
于 2012-09-17T14:54:35.940 回答
3

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

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

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

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

  • 如果您认为每个请求将花费大致相同的时间,那么您可以拆分工作并在启动每个线程之前为每个线程分配一部分工作。

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

于 2012-09-17T13:47:33.990 回答
0

检查您Maximum number of running JRun threads在 ColdFusion Administrator 中的 Request Tuning 选项卡下的设置。默认值为 50。

于 2012-09-17T13:31:05.047 回答