[dmd-concurrency] shutting down

Michel Fortin michel.fortin at michelf.com
Thu Jan 21 14:59:47 PST 2010


Le 2010-01-21 à 15:14, Andrei Alexandrescu a écrit :

> I agree we shouldn't put too much faith in the default shutdown method. I just want to choose a default that's reasonable.
> 
> Let me make a counterexample: pthreads have terrible defaults, i.e. it tears down everything without warning when main() exits. Virtually every example in Butenhof's book must use calls that override that crappy default. Look e.g. here:
> 
> http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
> 
> /* Wait till threads are complete before main continues. Unless we  */
> /* wait we run the risk of executing an exit which will terminate   */
> /* the process and all threads before the threads have completed.   */
> 
>   pthread_join( thread1, NULL);
>   pthread_join( thread2, NULL);
> 
>   exit(0);
> 
> Not to mention that that Einstein calls exit(0) as the last line in main().

That's C. In C there is no static module destructor running at the end. It looks like a way to make the point explicitly clear that all threads get trashed after this. Calling "exit(0)" in main isn't so bad, it's the same "return 0;". But I agree that it sets a bad example for the general case where you are not in main.


> So I'd be happy to define a reasonable default that does allow simple, meaningful applications to be written, without disallowing people who write servers from doing what they want to do.

Well, you don't have much choice. Either you kill the threads or you wait for them to terminate. We could add an optional timeout to the shutdown procedure, but I think the default should be to never timeout.

I think my Thread Termination Protocol covers termination in a scalable manner by sending termination messages to all threads. For threads not listening to messages, you need another shutdown mechanism. Sometime you can use a sudden termination flag. Here is how it could work:

	void someEventHandlingThread() {
		while (1) {
			allowSuddenTermination = true;
			auto event = waitForSomeEvent();
			
			// avoid terminating the thread in the middle of event handling.
			allowSuddenTermination = false;
			witch (event.type) {
				case DONE:
					return;
				case HELLO:
					runHelloHandshakeWithNeighbor();
					break;
			}

		}
	}

Pretty easy to use: you just set a flag to true while the thread can be suddenly terminated and false when you don't want it to be interrupted. Assuming it doesn't hold any lock while sudden termination is allowed, the shutdown procedure can just freeze the thread before calling safely the module destructors.

Other threads that need to be shutdown includes threads spawn by external libraries, not all written in D. For those written in D, they should answer to the Terminate message. For those not written in D, you'll always need custom cleanup code, although a D wrapper could make them respond to a Terminate message.

Concentrating on the shutdown procedure as a mean to make the application quit faster has its limit if you want to keep things clean. I'll say that the best way to make sure an app closes rapidly is to make sure each thread can terminate rapidly. We should concentrate on making it easy to write threads that terminate rapidly by making blocking APIs that do the right thing. But that's probably another subject for another thread, a mailing list thread I mean. :-)

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/





More information about the dmd-concurrency mailing list