tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: using of fork() in multithreaded application
> Date: Wed, 22 Jan 2025 16:47:13 +0100
> From: Peter Skvarka <ps%softinengines.com@localhost>
>
> On my NetBSD 10.1 I am trying to run multithreaded application where
> first are created several threads and then is called fork() from main
> thread.
> Forked child then calls execvp() .
> Passed command line (in argv argument) is "gcc", "-dumpversion".
>
> Application freezes because it waits for finishing child and ps -auxd
> shows child process "(gcc)"
> with flag zombie.
>
> I have two questions:
> Is safe using of fork() in NetBSD 10.1 in mutlithreaded application ?
Generally yes, with the caveat that it is difficult for applications
to use correctly.
For example, if you have any application-specific locks, you usually
have to take them carefully in a pthread_atfork handler to avoid
deadlock in the child.
Do you have a minimal reproducer for the unexpected behaviour you're
seeing? I just tried with the attached program and it worked fine.
$ ./hack
10.5.0
thread ran
$
> Does NetBSD 10.1 support "set follow-fork-mode child" when used
> /usr/bin/gdb ? I can step through source code of forked child only
> on-two lines not more.
Not sure offhand if it works, but if it doesn't work it's probably a
bug that should be reported separately (https://gnats.NetBSD.org).
#include <sys/wait.h>
#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
pthread_mutex_t m;
void *
runthread(void *cookie)
{
int error;
if ((error = pthread_mutex_lock(&m)) != 0)
errc(1, error, "pthread_mutex_lock");
printf("thread ran\n");
if ((error = pthread_mutex_unlock(&m)) != 0)
errc(1, error, "pthread_mutex_lock");
return NULL;
}
int
main(void)
{
pthread_t t;
pid_t pid, child;
int error;
if ((error = pthread_mutex_init(&m, NULL)) != 0)
errc(1, error, "pthread_mutex_init");
if ((error = pthread_mutex_lock(&m)) != 0)
errc(1, error, "pthread_mutex_lock");
if ((error = pthread_create(&t, NULL, &runthread, NULL)) != 0)
errc(1, error, "pthread_create");
pid = fork();
switch (pid) {
case -1:
err(1, "fork");
case 0:
execvp("gcc", (char *[]){"gcc", "-dumpversion", NULL});
err(1, "execvp");
default:
break;
}
if ((child = waitpid(pid, NULL, 0)) == -1)
err(1, "waitpid");
if (child != pid) {
errx(1, "waitpid returned %ld, expected %ld",
(long)child, (long)pid);
}
if ((error = pthread_mutex_unlock(&m)) != 0)
errc(1, error, "pthread_mutex_lock");
if ((error = pthread_join(t, NULL)) != 0)
errc(1, error, "pthread_join");
return 0;
}
Home |
Main Index |
Thread Index |
Old Index