On 12/18/06, Zoran Vasiljevic <[EMAIL PROTECTED]> wrote:
On 18.12.2006, at 19:57, Stephen Deasey wrote: > > > One thing I wonder about this is, how do requests average out across > all threads? If you set the conn threads to exit after 10,000 > requests, will they all quit at roughly the same time causing an > extreme load on the server? Also, this is only an option for conn > threads. With scheduled proc threads, job threads etc. you get > nothing. > Well, if they all start to exit at the same time, they will serialize at the point where per-thread cache is pushed to the shared pool.
I was worried more about things like all the Tcl procs needing to be recompiled in the new interp for the thread, and all the other stuff which is cached. If threads exit regularly, say after 10,000 requests, and the requests average out over all threads, then your site will regularly go down, effectively. It would be nice if we could make sure the thread exits were spread out. Anyway...
> I think some people are experiencing fragmentation problems with > ptmalloc -- the Squid and OpenLDAP guys, for example. There's also > the malloc-in-one-thread, free-in-another problem, which if your > threads don't exit is basically a leak. Really a leak? Why? Wouln't that depend on the implementation?
Yes, and I thought that was the case with Linux ptmalloc, but maybe I got it wrong or this is old news... This program allocates memory in a worker thread and frees it in the main thread. If all free()'s put memory into a thread-local cache then you would expect this program to bloat, but it doesn't, so I guess it's not a problem (at least not on Fedora Core 5). #include <tcl.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> #define MemAlloc malloc #define MemFree free void *gPtr = NULL; static void Thread(void *arg); static void PrintMemUsage(const char *msg); int main (int argc, char **argv) { Tcl_ThreadId tid; int i; PrintMemUsage("start"); for (i = 0; i < 100000; ++i) { Tcl_CreateThread(&tid, Thread, NULL, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE); Tcl_JoinThread(tid, NULL); MemFree(gPtr); gPtr = NULL; } PrintMemUsage("stop"); } static void Thread(void *arg) { assert(gPtr == NULL); gPtr = MemAlloc(1024); assert(gPtr != NULL); } static void PrintMemUsage(const char *msg) { FILE *f; int m; f = fopen("/proc/self/statm", "r"); if (f == NULL) { perror("fopen failed: "); exit(-1); } if (fscanf(f, "%d", &m) != 1) { perror("fscanf failed: "); exit(-1); } fclose(f); printf("%s: %d\n", msg, m); }