LINUX.ORG.RU

SIGKILL и «легковесные» дочки


0

1

Подскажите, как правильно удалять дочерние потоки из памяти после завершения родительского процесса с помощью сигнала SIGKILL?

Думал сделать примерно так:

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sched.h>
#include <sys/wait.h>

static time_t current_sec = 0;
static volatile long int counter = 0;

int thread_f( void *a ) {

	while( ++counter < 300 ) {

		if( (current_sec + 3) < time(0) ) break;
		sleep( 1 );

	}

	printf( "(i) closing thread %d, %s\n", getpid(),
		counter < 300 ? "parent died... :(" : "everything is OK!" );

	return 0;
}

#define N_THREADS 10

int main( int n, char** a ) {

	int i;
	pid_t tid[ N_THREADS ];
	char tstack[ N_THREADS<<12 ];

	current_sec = time(0);

	for( i=0; i<N_THREADS; ++i ) {
		tid[ i ] = clone( thread_f, tstack + ((i+1)<<12),
			CLONE_FILES|CLONE_FS|CLONE_SIGHAND|CLONE_SYSVSEM|CLONE_VM, 0 );
	}

	while( counter < 300 ) {
		current_sec = time(0);
		usleep( 500000 );
	}

	for( i=0; i<N_THREADS; ++i ) waitpid( tid[ i ], 0, 0 );

	printf( "(i) closing parent\n" );

	return 0;
}

Но есть нюансы. Например малая точность определения отсутствия предка, а также возможен случай когда предка просто усыпили с помощью SIGSTOP.


> как правильно удалять дочерние потоки из памяти после завершения родительского процесса с помощью сигнала SIGKILL?

Они сдохнут все разом.

tid[ i ] = clone( thread_f, tstack + ((i+1)<<12),

CLONE_FILES|CLONE_FS|CLONE_SIGHAND|CLONE_SYSVSEM|CLONE_VM, 0 );

pthread_create!

const86 ★★★★★ ()
Ответ на: комментарий от const86

угу, у POSIX-потоков в этом отношении конечно плюс, но мне нужно именно для «легковесных» дочерних процессов организовать подобную синхронизацию...

mrs ()

man prctl


PR_SET_PDEATHSIG (since Linux 2.1.57)
Set the parent process death signal of the calling process to arg2 (either a signal
value in the range 1..maxsig, or 0 to clear). This is the signal that the calling
process will get when its parent dies. This value is cleared for the child of a
fork(2).

Murr ★★ ()
Ответ на: комментарий от Murr

спасиб!

нашел еще один способ, нужно при клонировании добавить флажок CLONE_THREAD, что в общем-то наверное и сводится к установке DEATHSIG...

еще раз убеждаюсь, что в мане хранится невероятное множество тайн на которые обращаешь внимание при каждом новом прочтении! ;)

mrs ()
Ответ на: комментарий от Murr

Кстати, в продолжении темы, а может ли какой-либо процесс иметь несколько родителей, чтобы получать от всех родителей сигналы при их смерти?

mrs ()
Ответ на: комментарий от mrs

> добавить флажок CLONE_THREAD

сводится к установке DEATHSIG


не, это совершенно разное.

с CLONE_THREAD, это почти pthread_create(). выход
по exit_group() из любого потока означает выход всех.
а в glibc exit() вызывает exit_group().

может ли какой-либо процесс иметь несколько родителей


нет.

кстати, не советовал бы пользоваться clone(CLONE_VM).
это поломано в glibc, и вроде чинить не собираются.
пруфа не будет, тк я забыл что/где именно там случилось.
что-то с runtime linker.

idle ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.