fbpx
Skip to main content

[LA] Linux avanzato 2008

Di più
17 Anni 1 Mese fa #83170 da Gabriele
Risposta da Gabriele al topic [LA] Linux avanzato 2008

Mio d.io, smoking man, bovet è entrato in te....questi esercizi dove li hai tirati fuori?

AHAH!!! è vero, spero che bovet non tragga ispirazione da queste tracce!!! io stavo invece riprovando cose vecchie ed un po' più semplici, ma mi sono accorto di una cosa che non ho capito. il codice è questo:
/*
PROVA DI PROGRAMMAZIONE DEL 10/10/2006



Il processo padre crea 3 processi clone, memorizza i pid dei 3 processi clone

appena creati e si mette in attesa della terminazione del primo di essi. 



Ogni processo clone ha un tempo di esecuzione sensibilmente diverso da quello 

degli altri compreso tra 5 e 25 secondi (usare le funzione rand() e sleep() per

ottenere cio').



Il processo padre aspetta un segnale di tipo SIGUSR1 da parte del

clone che termina per primo. Ricevuto tale segnale, il processo padre elimina

mediante kill() i rimanenti due cloni. 



Verificare la correttezza del programma mediante "strace <nome_eseguibile>"
*/

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

#define STACK_SIZE 1024

int pids[3];

void handler(int sign)
{
	printf("attivato handler SIGUSR1\n");
	
	int i, pid, status = 0;
	
	if ((pid = wait(&status)) < 0)
	{
		perror("errore in wait()\n");
	}
	
	for (i= 0; i < 3; i++)
	{
		if (pids[i] != pid)
		{
			if (kill(pids[i], SIGKILL) < 0)
			{
				printf("errore in kill() %d\n", pids[i]);
			}
			else
			{
				printf("eseguita kill() %d\n", pids[i]);
			}
		}
	}
	
	return;
}

int cloneFunc(void *arg)
{
	printf ("creato clone %d\n", getpid());
	
	srand(time(NULL));
	int sleepTime = (rand() % 21) + 5;
	
	printf ("clone %d dorme %d secondi\n", getpid(), sleepTime);
	
	sleep(sleepTime);
	
	kill(getppid(), SIGUSR1);
	
	return 1;
}

int main(int argc, char *argv[])
{
	signal(SIGUSR1, handler);
	
	int stack[3][STACK_SIZE];
	
	int i;
		
	for (i= 0; i < 3; i++)
	{
		sleep(1);
		
		if ((pids[i] = clone(cloneFunc, &stack[i][STACK_SIZE-1], CLONE_VM, NULL)) < 0)
		{
			printf("errore in clone() %d\n", i);
			exit(-1);
		}
	}
	
	pause();	
	
	exit(1);
}

dunque, la wait nell'handler segnala un errore no child processes, ma non capisco proprio perchè! voi avete idea? me ne sono accorto solo perchè ho messo il controllo sulla wait e la stampa dopo la kill, altrimenti avrei dato per scontato che funzionasse bene...

Si prega Accedi o Crea un account a partecipare alla conversazione.

Di più
17 Anni 1 Mese fa #83171 da Gabriele
Risposta da Gabriele al topic [LA] Linux avanzato 2008
P. S. = comunque vorrei far notare che questa era una prova di laboratorio del 2006... la difficoltà rispetto a quelle di quest'anno non mi sembra proprio la stessa... :(

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • COM_EASYSOCIAL_GUEST_NAME
  • Avatar di COM_EASYSOCIAL_GUEST_NAME
  • Visitatori
  • Visitatori
17 Anni 1 Mese fa #83175 da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008

Mio d.io, smoking man, bovet è entrato in te....questi esercizi dove li hai tirati fuori?

AHAH!!! è vero, spero che bovet non tragga ispirazione da queste tracce!!! io stavo invece riprovando cose vecchie ed un po' più semplici, ma mi sono accorto di una cosa che non ho capito. il codice è questo:
/*
PROVA DI PROGRAMMAZIONE DEL 10/10/2006



Il processo padre crea 3 processi clone, memorizza i pid dei 3 processi clone

appena creati e si mette in attesa della terminazione del primo di essi. 



Ogni processo clone ha un tempo di esecuzione sensibilmente diverso da quello 

degli altri compreso tra 5 e 25 secondi (usare le funzione rand() e sleep() per

ottenere cio').



Il processo padre aspetta un segnale di tipo SIGUSR1 da parte del

clone che termina per primo. Ricevuto tale segnale, il processo padre elimina

mediante kill() i rimanenti due cloni. 



Verificare la correttezza del programma mediante "strace <nome_eseguibile>"
*/

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

#define STACK_SIZE 1024

int pids[3];

void handler(int sign)
{
	printf("attivato handler SIGUSR1\n");
	
	int i, pid, status = 0;
	
	if ((pid = wait(&status)) < 0)
	{
		perror("errore in wait()\n");
	}
	
	for (i= 0; i < 3; i++)
	{
		if (pids[i] != pid)
		{
			if (kill(pids[i], SIGKILL) < 0)
			{
				printf("errore in kill() %d\n", pids[i]);
			}
			else
			{
				printf("eseguita kill() %d\n", pids[i]);
			}
		}
	}
	
	return;
}

int cloneFunc(void *arg)
{
	printf ("creato clone %d\n", getpid());
	
	srand(time(NULL));
	int sleepTime = (rand() % 21) + 5;
	
	printf ("clone %d dorme %d secondi\n", getpid(), sleepTime);
	
	sleep(sleepTime);
	
	kill(getppid(), SIGUSR1);
	
	return 1;
}

int main(int argc, char *argv[])
{
	signal(SIGUSR1, handler);
	
	int stack[3][STACK_SIZE];
	
	int i;
		
	for (i= 0; i < 3; i++)
	{
		sleep(1);
		
		if ((pids[i] = clone(cloneFunc, &stack[i][STACK_SIZE-1], CLONE_VM, NULL)) < 0)
		{
			printf("errore in clone() %d\n", i);
			exit(-1);
		}
	}
	
	pause();	
	
	exit(1);
}

dunque, la wait nell'handler segnala un errore no child processes, ma non capisco proprio perchè! voi avete idea? me ne sono accorto solo perchè ho messo il controllo sulla wait e la stampa dopo la kill, altrimenti avrei dato per scontato che funzionasse bene...


ciao! in effetti sto impazzendo.... :twisted:

L'errore è dovuto al fatto che usi wait in luogo di waitpid(-1,&status,__WCLONE). Infatti se aspetti un clone e ti dimentichi quel flag non funziona (e impazzirai come me.. ehehe! :) ) .
__WCLONE
Wait for "clone" children only. If omitted then wait for "non-clone" children only

prova anche a togliere la pause() e mettere direttamente la waitpid() nel main: dovrebbe sbloccarti il processo padre anche un segnale.

In ogni caso trovi questo esercizio tra quelli di sistemi operativi (mi pare sia kill_slow_brothers.c)

ciao!

PS: Quale vi sembra l'esercizio + difficile in assoluto degli anni precedenti?

Si prega Accedi o Crea un account a partecipare alla conversazione.

Di più
17 Anni 1 Mese fa #83178 da Gabriele
Risposta da Gabriele al topic [LA] Linux avanzato 2008

ciao! in effetti sto impazzendo.... :twisted:

L'errore è dovuto al fatto che usi wait in luogo di waitpid(-1,&status,__WCLONE). Infatti se aspetti un clone e ti dimentichi quel flag non funziona (e impazzirai come me.. ehehe! :) ) .
__WCLONE
Wait for "clone" children only. If omitted then wait for "non-clone" children only

prova anche a togliere la pause() e mettere direttamente la waitpid() nel main: dovrebbe sbloccarti il processo padre anche un segnale.

In ogni caso trovi questo esercizio tra quelli di sistemi operativi (mi pare sia kill_slow_brothers.c)

ciao!

PS: Quale vi sembra l'esercizio + difficile in assoluto degli anni precedenti?

Mitico come sempre! Devo andare a dare un'occhiata a questi esercizi di SOP! ma dove stanno?
Ho messo pausa e handler giusto per coerenza con il testo, per evitare che un altro segnale potesse generare quel comportamento! Ma in effetti credo che a lui basti che funziona... Sarà meglio fare le cose più semplici!

Si prega Accedi o Crea un account a partecipare alla conversazione.

Di più
17 Anni 1 Mese fa #83180 da Gabriele
Risposta da Gabriele al topic [LA] Linux avanzato 2008
Gli esercizi più difficili... sono senza dubbio quelli che hai creato tu! :D

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • COM_EASYSOCIAL_GUEST_NAME
  • Avatar di COM_EASYSOCIAL_GUEST_NAME
  • Visitatori
  • Visitatori
17 Anni 1 Mese fa #83191 da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
Gli esercizi di sop stanno qui: so.sprg.uniroma2.it/ ti consiglio le esercitazioni dalla 4 in poi (la 5 è sui segnali).

Io avrei alcune domande sulla teoria cui spero qualcuno potrà/vorrà rispondere:

1) sulle lezioni 19-20 (inizializzazione) bisogna studiare tutto per filo e per segno? Ci sono descrizioni generiche di alcune funzioni (un botto) con riferimenti ai capitoli di Understanding the linux kernel... Tocca imparare tutte quelle cose?
2)Invece riguardo alle lezioni 16-17-18: ci sono nelle dispense 2-3 alberi di chiamate per la read e la write, quel codice va studiato?
3) Ammetto che per cause di forza maggiore non ho potuto seguire il corso, ma mi sembra che siano davver un botto di cose spiegate malissimo (sto facendo avanti e indietro tra dispense e il libro da quasi 20 giorni e ancora non ho finito, anzi).. Ad esempio la segmentazione (che sicuramente sarà stata tra le conoscenze preliminari che non avevo, anche se a sistemi operativi parlo' solo di paginazione) la dà proprio per scontata... Per non parlare del linkaggio.. E' un problema solo mio o avete avuto anche voi la stessa impressione?

ciao e grazie a tutti coloro che vorranno illuminarmi!

Si prega Accedi o Crea un account a partecipare alla conversazione.