pthread+exec question

Eyal Lebedinsky eyal at
Sun Feb 10 11:41:27 EST 2002

I am trying to undersnatd the interaction between threads and
exec(). The attached program demonstrates how the exec() behaves
differently when issued from inside a thread (./p) or directly
from main (./p x). In the former case the shell proceeds when
the exec is issued rather than wait for the completion of the

The problem is that the exec'ed program takes over the pid of
the thread rather than of main(), and the original process
exits, letting my shell proceed rather than wait.

How do I prevent this? I have a need to exec() from inside a
thread and not release a wait()ing parent at that point.

I tried playing with pthread_attr_setscope() but got incorrect
results: non-zero return code and no perror. Just change to
and see. Anyway, it probably is unrelated.

I looked into process groups and got no solution either.

Eyal Lebedinsky (eyal at <>
-------------- next part --------------
#include <stdio.h>
#include <sys/types.h>	/* pid_t */
#include <unistd.h>
#include <pthread.h>

static pid_t	main_pid;
static pid_t	main_pgrp;
static pid_t	thread_pid;
static pid_t	thread_pgrp;

check (char *func, int rc)
	if (rc) {
		fprintf (stderr, "%s rc=%d", func, rc);
		perror (" ");
		exit (1);

void *
thread (void *parm)
	thread_pid = getpid ();
	thread_pgrp = getpgrp ();
	fprintf (stderr,
		"thread pid is %ld pgrp is %ld\n",

	execl ("/bin/sh", "sh", "-c", "(sleep 1 ; echo hi from $$)", NULL);
	/* not reached */

	return (NULL);

main (int argc, char **argv, char **envp)
	pthread_attr_t	attr;
	pthread_t	th;
	void		*rc;

	main_pid = getpid ();
	main_pgrp = getpgrp ();
	fprintf (stderr,
		"main pid is %ld pgrp is %ld\n",

	if (argc > 1)
		rc = thread (NULL);
	else {
		check ("pthread_attr_init", 
			pthread_attr_init (&attr));
		check ("pthread_attr_setscope", 
			pthread_attr_setscope (&attr,
		check ("pthread_attr_setdetachstate", 
			pthread_attr_setdetachstate (&attr,
		check ("pthread_create",
			pthread_create (&th,	/* thread id */
				&attr,		/* pthread_attr */
				thread,		/* start routine */
				NULL));		/* start routine arg */
		check ("pthread_join",
			pthread_join (th, &rc));
	/* not reached */

	return (0);

More information about the linux mailing list