lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Mon, Dec 30, 2013 at 12:03 AM, Philipp Janda <siffiejoe@gmx.net> wrote:
Am 30.12.2013 05:47 schröbte Rena:
On Sun, Dec 29, 2013 at 11:28 PM, Philipp Janda <siffiejoe@gmx.net> wrote:

Am 30.12.2013 03:38 schröbte Rena:


3) I wanted the parent thread to be able to use a "fire-and-forget"
design:
create a thread and let it go off to work on something without having to
keep track of it.


That's what `pthread_detach` is for, but I guess you want to wait for all
running threads before shutting down the main thread, right?


That's correct. Otherwise, unless I'm terribly confused, when the main
thread exits, child threads can be prematurely killed (especially if they
haven't yet noticed the signal to run).


When the parent thread shuts down, it will loop through its list of
children and pthread_join() all of them waiting for them to shut down. At
this point it'd be safe to delete them. Trouble is, if the parent thread
runs for a very long time and creates thousands of threads, then this
basically a memory leak - all those threads which have shut down ages ago
will still have a Thread object in the child list until the server is shut
down.


I'd use the membership in the parent's list as an indicator whether a
thread should detach itself before exiting, and a reference count for
determining if a child thread can free its Thread structure itself or has
to let a `__gc` metamethod handle that. You will still need to protect the
parent's list and the reference count with mutexes, but only for the time
it needs to read/modify them.


I'm not sure quite what you mean by this (by detach, you mean the thread
should pthread_detatch() itself before exiting, and the parent not wait for
it to terminate? what's the benefit of this?),

The benefit is that a finished child thread can delete itself from its parent's list (and free its resources) as soon as it is done (the 'fire-and-forget' part without the "memory leak" mentioned above), while all active threads are still in the list in a non-detached state so that the parent can wait for them before shutting down.

Philip

I see. But after further consideration, I don't think a reference count can work either. That needs to be protected by a mutex, and where do I store said mutex? Consider what happens if both the thread and its parent want to dereference it at the same time:

void Thread::Delete() {
    this->mutex_refcount.lock();
    this->refcount--;
    if(this->refcount == 0) delete this;
    //we can no longer unlock this->mutex_refcount, so the other thread is
    //going to block forever or segfault
}

or:

void Thread::Delete() {
    this->mutex_refcount.lock();
    this->refcount--;
    this->mutex_refcount.unlock();
    //now there's a race condition; between these two lines, the other thread
    //could decrement refcount too.
    if(this->refcount == 0) delete this;
}

plus both variants have the potential problem, that one thread could delete the Thread (and thus the mutex) just before the other thread attempts to lock mutex_refcount, causing a segfault or hang.


--
Sent from my Game Boy.