<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>deffbeff &#187; multithreaded</title>
	<atom:link href="http://www.deffbeff.com/blog/category/multithreaded/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.deffbeff.com/blog</link>
	<description>Mostly software</description>
	<lastBuildDate>Thu, 03 Dec 2009 23:00:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Multithreading and fork()</title>
		<link>http://www.deffbeff.com/blog/2009/01/multithreading-and-fork/</link>
		<comments>http://www.deffbeff.com/blog/2009/01/multithreading-and-fork/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 18:48:33 +0000</pubDate>
		<dc:creator>Matthew Gilbert</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[multiprocess]]></category>
		<category><![CDATA[multithreaded]]></category>

		<guid isPermaLink="false">http://www.deffbeff.com/blog/?p=12</guid>
		<description><![CDATA[Prevent hangs in multi-threaded/multi-process code by minimizing code that runs in the child process after a fork.]]></description>
			<content:encoded><![CDATA[<p>I recently wrote a tool in C++ that would run a large number of tasks in the background, parse the results, and print simple pass/fail information for each task. I used the tool as an opportunity to start using boost::threads which resembles the upcoming C++0x threading support. The multithreaded portion of the code was very simple, all contained in my own <a href="http://en.wikipedia.org/wiki/Future_(programming)">futures</a> class.</p>
<p>Everything ran well, except occasionally a test would time-out. I figured this was a problem with how I was setting up the stdin/stdout pipes to the subtask (each thread would fork() to run the sub-task and use a timed poll() to wait for results). On Friday, I finally sat down to figure out what was causing the test hangs.</p>
<p>Turns out it had nothing to do with sub-task input and output. Each thread is responsible for one subtask. The thread creates the necessary pipes, performs some other book keeping, and then forks. The child process then transforms a vector of command line arguments to an argv[] style array, sets up stdin/stdout with dup2, and calls execvp.</p>
<p>To debug, I modified the parent to print the hung pid which I would attach to using gdb. Every time I attached, the child process was stuck in the same place: waiting on a mutex used by the std::string implementation.</p>
<p>The child process doesn’t use any threading functions, and all of its parameters are passed on the stack. However, I didn’t consider that most of libstdc++ is thread safe (I can’t find a reference that specifies exactly what is and isn’t thread safe in glibc/libstdc++). Each time the process forked, it risked forking while the underlying std::string memory mutex was being held by another thread. As documented in the pthread_atfork man page, those mutexes are not useable after the fork, and must be re-initialized with pthread_mutex_init in the child process. This caused the child process to hang indefinitely waiting on a mutex that would be released only in the parent’s process space.</p>
<p>The solution was to move the std::string processing before the fork. That left only dup2 calls and the execvp after the fork. Result: no more hangs!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.deffbeff.com/blog/2009/01/multithreading-and-fork/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
