CFThread - Don't Abuse It
August 07, 2007
I love the fact that you can now create threads with CFML in ColdFusion 8, however as Spiderman can tell you with great power comes great responsibility.
Using threads can increase the performance of your application, however using threads can also decrease performance. And the problem is that CF8 makes it oh so easy to create threads.
One of the potential performance problems you can run into from using threads is called context switching, which can be explained as follows:
- Your boss tells you to work on Project A at 8AM
- At 8:15 your boss tells you you need to work on Project B, so you close all the code you were working on, and open up Project B.
- At 8:25 you need to fix an important bug in project A.
- At 8:30 you get a phone call about Project C, you have to pull up those files.
- Back to project B at 8:35, project A at 8:40, and project D at 8:45
How could you get anything done under the above circumstances? Well computer processors have trouble with that exact problem as well, and they call that context switching. As threads take turns executing their previous state or context must be loaded again when execution of a thread switches between threads. Process and thread scheduling is actually one of the most important parts of an operating system, and includes very well though out algorithms - it's the sort of thing people do their doctoral thesis on. You can read more about it context switching on Wikipedia.
The cost of creating a new thread, is another performance issue associated with using threads. In ColdFusion this is mitigated a bit by using a thread pool, but you can still create performance problems if too much time is spent creating new threads. There is a setting in CF Administrator which limits the number of threads that can be created with CFTHREAD, if this value is reached, the threads will queue up, and wait to execute.
The third issue you may face is shared resource contention. Suppose you have a lot of threads trying to use a shared resource, such as an application variable or file. You can create a bottle neck due to the locking / access synchronization of that resource.
In the end the only way to know if your application will benefit from using threads is to test and tune it under load, which is a something most developers don't do. So I am wondering if we will start to see a lot of performance problems due to overuse of the
CFTHREAD tag, what do you think?
Trackback Address: 650/ABC6950BA34279C9599747B20BBDD4CC
I'd like to add another big thing people need to look out for. It is easy to fire off threads and never check to see how they ended up. I know I've made this mistake. If you join your threads, you should check the status, and if you don't, you should log, store in RAM/DB, whatever, just have _something_ to notice if an error was thrown.
How does "priority" play into this. Let's say you don't need to wait for a thread to finish, will setting all of the launched threads to LOW priority help lessen the context-switching burden?
@Ray - Excellent point Ray, thanks.
@Ben - I would think that LOW priority threads would suffer less from context switching, but the extent would probably depend on the thread scheduling algorithm used by the Operating System, and possibly the JVM's threading implementation. Reguardless, though I would say it is probably a really good idea to use a low priority thread for any thread doing a background process that you don't need to wait for.
That brings up an interesting use case for CFTHREAD, suppose you have a scheduled task that runs once a day, it may be a good idea for that task to run in a low priority thread, because otherwise the task will run in a normal priority thread.
There should be a way, when working with scheduled tasks, to tell CF you want the thread to run in a low, normal, or high priority. If folks think that makes sense, I'll log it as an ER.
Makes sense to me Ray. It would also be kind of neat if you could specify a request thread priority via cfsetting tag, that would be pretty cool, but I'm not sure if the overhead of changing priorities would be worth it.
I think that this could be detrimental to ColdFusion's image in the industry. Right now ColdFusion gets blamed for all sorts of things that are not its fault simply because ColdFusion is where the error is thrown, i.e. db errors etc. Now adding cfthread, I could easily see a novice or even an intermediate programmer spawning threads everywhere just because its a fun new toy and, just like you said, never load testing. Once the site gets more than 5 hits, it locks up. And because its a ColdFusion site, CF will be blamed for the lock up, when in reality, the problem is with the programmer (the code), not CF
I suspect that this may be a contributing factor to only allowing 2 concurrent threads in the Standard License (i.e. programmers with less experience?)
Wait, "only allowing 2 concurrent threads"... is that true?
At the very bottom, look for the cross annotation.
At least that was my understanding...
Discussion of people who do not understanding threading model at all...
Thread pool and thread creation are mutually exclusive...
Lowering thread priority has zero impact on context switching overhead...
And so on, and so on...
Macromedia Director MX v10.0 - $49.95..!!! http://forums.lionsgate.com/showthread.php?p=139944
Two additional spawned threads means 3-threads total per request -- the one your request started in, plus two additional threads... My guess would be that also doesn't change the limit of the total number of spawned threads across the server, i.e. if there are 5 concurrent requests and you set it in cfadmin to allow 15, then they can get 15 threads across those 5 requests, but they couldn't get 15 with any less than 5 concurrent users. And as well I believe that the threads queue within the current request, so if you spawed 5 "simultaneous" threads, it would simply leapfrog the available 2 spawned threads until it finished those tasks.
I am having a problem with cfthread. We run a pretty well developed application, that gets over 1 million impressions per day. It runs on 2 loadbalanced Coldfusion servers. We decided to invest into software rather than hardware, especially since we need CF enterprise which could be costly.
Anyway, each impression needs to execute about 20 threads that query a third-party xml feed and then join them and display the results. So far it worked well for us when we had it at 5 threads per request. But now we do 20-30 requests and the servers are both crashing every 6-12 hours.
It seemed like the memory hit nearly 0 gb on our servers and then CF stopped working. I investigated all memory leak issues on the web and came up short of how that could be anywhere connected to cfthread.
I installed Oracle's BEA JROCKIT jvm to replace the SUN jvm, and the memory leak issue disappeared, probably due to their superior garbage collector. But now their JVM is crashing for other weird reasons due to CFQUERY - well not CFQUERY , because we actually query our database via Java functions since there were other CFQUERY pooling performance problems in the past. So our software is really tuned and customized to work the best it can on the least amount of hardware.
What I added to our CFTHREADs is the action=terminate after all threads are joined, which we haven't been doing so far. So far the servers have been stable last few hours but we'll need more time to actually determine if that was the issue or not.
So I am just curious what everyone recommends and if anyone experienced similar memory leak problems with cfthreads?
delete my topic, admins, plz
I read this and... that is exactly how my current workday goes. Don't be a Dev, Marketer, and IT at the same time in a company that has a hiring freeze.