|
cfthread
DescriptionThe cfthread tag
enables you to create threads, independent streams of code execution,
in your ColdFusion application. You use this tag to run or end a
thread, temporarily stop thread execution, or join together multiple
threads.
Syntaxjoin
<cfthread
required
name="thread name[,thread name]..."
optional
action="join"
timeout="milliseconds"/>
run
<cfthread
required
name="thread name"
optional
action="run"
priority="NORMAL|HIGH|LOW"
zero or more application-specific attributes>
Thread code
</cfthread>
sleep
<cfthread
required
action="sleep"
duration="milliseconds"/>
terminate
<cfthread
required
action="terminate"
name="thread name"/>
For all actions
except run, the cfthread tag must
have an empty body and be followed immediately by a </cfthread> end
tag, or must have no end tag and have a slash before the tag closure,
as in <cfthread action="sleep" duration="1000"/>.
Note: You can specify this tag’s attributes in an attributeCollection attribute
whose value is a structure. Specify the structure name in the attributeCollection attribute
and use the tag’s attribute names as structure keys.
HistoryColdFusion
8: Added this tag
Attributes
Attribute
|
Req/Opt
|
Default
|
Applies to
|
Description
|
action
|
Optional
|
run
|
All
|
The action to take, one of the following
values:
join: Makes the current
thread wait until the thread or threads specified in the name attribute
complete processing, or until the period specified in the timeout attribute
passes, before continuing processing. If you don’t specify a timeout
and the thread you are joining to doesn’t finish, the current thread
also cannot finish processing.
run: Creates a thread and starts it processing.
Code in the cfthread tag body runs simultaneously
and independently of page-level code and code in other cfthread tags.
sleep: Suspends the current thread’s processing
for the time specified by the duration attribute.
Equivalent to the Sleep function.
terminate: Stops processing of the thread
specified in the name attribute. If you terminate
a thread, the thread scope includes an ERROR metadata structure with
information about the termination.
|
duration
|
Required
|
|
sleep
|
The number of milliseconds for which to
suspend thread processing.
|
name
|
Optional, Required, if action = "join" or "terminate"
|
|
join
run
terminate
|
The name of the thread to which the action
applies:
terminate: The name of
the thread to stop.
join: The name of the thread or threads
to join to the current thread. To specify multiple threads, use
a comma-delimited list.
run: The name to use to identify the thread
being created.
|
priority
|
Optional
|
NORMAL
|
run
|
The priority level at which to run the thread.
The following values are valid:
Higher priority
threads get more processing time than lower priority threads. Page-level
code, the code that is outside of cfthread tags,
always has NORMAL priority.
|
timeout
|
Optional
|
0
|
join
|
The number of milliseconds that the current
thread waits for the thread or threads being joined to finish. If
any thread does not finish by the specified time, the current thread
proceeds.
If the attribute value is 0, the following action
occurs:
The current thread continues waiting until
all joining threads finish.
If the current thread is the page thread, the page continues
waiting until the threads are joined, even if you specify a page
time-out.
|
UsagePage-level
code (code outside any cfthread tags) executes
in its own thread, referred to as the page thread. Only the
page thread can create other threads. A thread that you create cannot
create a child thread.
Note: If a thread never
completes processing (is hung), it continues to occupy system resources.
You can use the ColdFusion Sever Monitor to check for and terminate
hung threads.
ColdFusion makes a complete (deep) copy of
all the attribute variables before passing them to the thread, so
the values of the variables inside the thread are independent of
the values of any corresponding variables in other threads, including
the page thread. Thus, the values passed to threads are thread safe because
the attribute values cannot be changed by any other thread.
Thread scopesEach thread has three special scopes:
The thread-local scope is an implicit scope that contains
variables that are available only to the thread, and exist only
for the life of the thread.
The Thread scope is available to the page and to all other
threads started from the page. Its data remains available until
the page and all threads started from the page finish, even if the
page finishes before the threads complete processing.
The Attributes scope contains attributes that are passed
to the scope, and is available only within the thread and only for
the life of the thread.
For detailed information about using
ColdFusion scopes in threads, see Using ColdFusion
Threads in the Developing ColdFusion Applications.
All
threads in a page share a single Variables scope, so you can use
it for data that is common across all threads. You must be careful
to lock access to the variables, if necessary, to prevent deadlocks
or race conditions between threads.
Note: When
ColdFusion uses a connector to access the web server, after the
page gets completed, the CGI and Request scopes are not accessible
to threads that you create by using the cfthread tag.
This limitation does not apply if you use the integrated web server
or if you run ColdFusion as a J2EE application.
Metadata variablesThe thread scope contains the following variables
that provide information about the thread (metadata):
Variable
|
Description
|
ElapsedTime
|
The amount of processor time that was spent
handling the thread.
|
Error
|
The structure that is generated if an error
occurs during thread execution. The structure contains the keys
that you can access in a cfcatch tag.
If
an error occurs in a thread, page-level processing is not affected,
and ColdFusion does not generate an error message. The thread with
the error terminates and the page-level code or other threads can get
the error information from the Error field and handle the error
appropriately. For detailed information, see Handling
ColdFusion thread errors in the Developing ColdFusion Applications.
|
Name
|
The thread name.
|
Output
|
Output that is generated by the thread.
A thread cannot display output; page-level code must use this variable
to display thread results. For detailed information, see Handling
thread output in the Developing ColdFusion Applications.
|
Priority
|
The thread processing priority, as specified
in the cfthreadpriority attribute.
The following values are valid:
|
Starttime
|
The time at which the thread began processing,
in ColdFusion date-time format.
|
Status
|
The current status of the thread; one of
the following values:
NOT_STARTED:
The thread has been queued but is not processing yet.
RUNNNG: The thread is running normally.
TERMINATED: The thread stopped running due
to a cfthread tag with a terminate action,
an error, or an administrator action.
COMPLETED: The thread ended normally.
WAITING: The thread has executed a cfthread tag
with action="join", but one or more threads being
joined has not completed.
|
ExampleThe
following example uses three threads to get the results of three
RSS feeds. The user must submit the form with all three feeds specified.
The application joins the threads with a time-out of 6 seconds,
and displays the feed titles and the individual item titles as links.
<!--- Run this code if the feed URL form has been submitted. --->
<cfif isDefined("Form.submit")>
<cfloop index="i" from="1" to="3">
<!--- Use array notation and string concatenation to create a variable
for this feed. --->
<cfset theFeed = Form["Feed"&i]>
<cfif theFeed NEQ "">
<!--- Use a separate thread to get each of the feeds. --->
<cfthread action="run" name="t#i#" feed="#theFeed#">
<cffeed source="#feed#"
properties="thread.myProps"
query="thread.myQuery">
</cfthread>
<cfelse>
<!--- If the user didn't fill all fields, show an error message. --->
<h3>This example requires three feeds.<br />
Click the Back button and try again.</h3>
<cfabort>
</cfif>
</cfloop>
<!--- Join the three threads. Use a 6 second time-out. --->
<cfthread action="join" name="t1,t2,t3" timeout="6000" />
<!--- Use a loop to display the results from the feeds. --->
<cfloop index="i" from="1" to="3">
<!--- Use the cfthread scope and associative array notation to get the
Thread scope dynamically. --->
<cfset feedResult=cfthread["t#i#"]>
<!--- Display feed information only if you got items,
for example the feed must complete before the join. --->
<cfif isDefined("feedResult.myQuery")>
<cfoutput><h2>#feedResult.myProps.title#</h2></cfoutput>
<cfoutput query="feedResult.myQuery">
<p><a href="#RSSLINK#">#TITLE#</a></p>
</cfoutput>
</cfif>
</cfloop>
</cfif>
<!--- The form for entering the feeds to aggregate. --->
<cfform>
<h3>Enter three RSS Feeds</h3>
<cfinput type="text" size="100" name="Feed1" validate="url"
value="http://rss.adobe.com/events.rss?locale=en"><br />
<cfinput type="text" size="100" name="Feed2" validate="url"
value="http://weblogs.macromedia.com/dev_center/index.rdf"><br />
<cfinput type="text" size="100" name="Feed3" validate="url"
value="http://rss.adobe.com/studio.rss?locale=en"><br />
<cfinput type="submit" name="submit">
</cfform>
|