There is an issue related to releasing Pthreads.

16 views
Skip to first unread message

themixup

unread,
Nov 12, 2025, 11:10:17 PM (19 hours ago) Nov 12
to emscripten-discuss
Hello,

I am writing to ask about an issue I'm facing where pthreads do not seem to be released properly.

In my React application, I need to perform a specific task every time the user provides keyboard input. My approach was to spawn a new thread for each key-press and then detach it.

However, after continuous typing, the application crashes.

When I checked the Chrome debugger, I could see dozens of "em-thread"s (Emscripten worker threads) accumulating. It appears that the threads I create are not terminating or being cleaned up, even after their work is complete.

The pattern I was using is as follows:
// This is called on every keyboard input
void CreateWorkerThread() {
    pthread_t thread;
    pthread_create(&thread, NULL, DoWork, NULL);
    pthread_detach(thread);
}

void* DoWork(void* arg) {
    // Perform a specific task...
    // I am certain this function finishes its execution.
    return NULL;
}

I have already implemented a workaround by changing my design to call pthread_create only once (using a persistent worker thread and a message queue), which has resolved the memory issue and the crash.

However, I am still curious why the original approach failed. Is it expected behavior that frequently creating and detaching threads in Emscripten will cause them to accumulate without being released? Is there a proper way to handle this "fire-and-forget" threading pattern?

Thank you for any insights.


본 이메일은 기밀 정보를 포함하고 있으며, 지정된 수신인에게만 전달되었습니다. 만약 귀하가 의도된 수신인이 아니라면, 이 이메일의 내용을 열람, 사용 또는 배포하는 것을 엄격히 금지합니다. 만일 이 이메일을 잘못 수신하셨다면, 즉시 삭제해 주시고 발신자에게 알려주시기 바랍니다.(This email contains confidential information and is intended solely for the designated recipient(s). If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the contents of this email is strictly prohibited. If you have received this email in error, please delete it immediately and notify the sender.)

Sam Clegg

unread,
Nov 12, 2025, 11:15:42 PM (19 hours ago) Nov 12
to emscripte...@googlegroups.com
Emscripten uses a worker pool.   I will create a new worker each time a pthread is created and there are no free workers in the pool. 

Assuming DoWork doesn't take too long then in your case the workers should be returned to the pool as re-used.

The total number of workers at any time will be the maximum number of simultaneous DoWork requests that you have had.   Because workers are fairly expensive to create we never currently shrink the pool.    In theory such an option could be added..

cheers,
sam

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/emscripten-discuss/7a2ad872-664e-46a1-88b2-b359886d2f30n%40googlegroups.com.

themixup

unread,
9:59 AM (8 hours ago) 9:59 AM
to emscripten-discuss

Thank you for the confirmation, Sam.

I fully understand the explanation (that the worker pool is designed never to shrink).

This aligns with my observations. During my testing, I noticed that even when I tried using the PTHREAD_POOL_SIZE and PTHREAD_POOL_SIZE_STRICT options, the number of threads still seemed to grow beyond the specified size during high-frequency input.

As I mentioned, I have already resolved the issue in my application by changing my design to use pthread_cond_wait (to manage a persistent worker and a queue), which avoids creating new threads repeatedly.

However, this leads me to a follow-up theoretical question:

I understand that for standard Web Workers, we are responsible for memory management and must call terminate() to properly release the worker and its resources.

Since Emscripten pthreads are implemented as Web Workers, I started to wonder: is it possible to manually terminate() an 'em-thread' (a worker created by Emscripten) from JavaScript to force the pool to shrink? Or is this a misguided approach that would break Emscripten's internal thread management?

I am curious if this is the wrong way to think about it. For reference, this is the standard JS pattern I am thinking of:

// JavaScript code
const workerURL = new URL('../workers/idb-worker.js', import.meta.url);
worker = new Worker(workerURL, { type: 'module' });
worker?.terminate();
worker = null;

2025년 11월 13일 목요일 오후 1시 15분 42초 UTC+9에 s...@google.com님이 작성:

Sam Clegg

unread,
12:46 PM (6 hours ago) 12:46 PM
to emscripte...@googlegroups.com
As of today, workers in the pool are only terminated when the program ends.  See `terninateAllThreads`: https://github.com/emscripten-core/emscripten/blob/f8611ebe049ad66349b953d358367e4abcd005ca/src/lib/libpthread.js#L170-L192.

If there is a use case for it we could add some kind of API for shrink the pool such as `emscirpten_pthread_pool_shrink(new_size)`, but so far we have not heard of any need for this since most application have a reasonable/stable upper bound on the number of possible workers/threads.

cheers,
sam

Reply all
Reply to author
Forward
0 new messages