fbpx
Skip to main content

[LA] Linux avanzato 2008

  • COM_EASYSOCIAL_GUEST_NAME
  • Avatar di COM_EASYSOCIAL_GUEST_NAME
  • Visitatori
  • Visitatori
17 Anni 2 Mesi fa #82663 da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
ciao ragazzi...
due domande veloci:
1. che distro, ke kernel e che gcc ci sono sui calcolatori del laboratorio LADI?
2. che editor conviene usare durante la prova? c'è kate o una cosa simile?

grassie ;)

ps. il prof stamane ha aggiunto altre due date per la prova al calcolatore

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 2 Mesi fa #82665 da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
In bocca al lupo a chi ha l'orale oggi o nei prossimi giorni! Fateci avere notizie! :)

Per chi fosse interessato, ho visto che ha messo le altre date per la prova di programmazione...

Infine, per chi come me fosse prossimo ad affrontare la 2a prova, volevo proporre di condividere gli esercizi più impegnativi che troviamo (o ci vengono in mente) e relative soluzioni da commentare insieme... che ne dite? :D

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

Di più
17 Anni 2 Mesi fa #82669 da Gabriele
Risposta da Gabriele al topic [LA] Linux avanzato 2008

In bocca al lupo a chi ha l'orale oggi o nei prossimi giorni! Fateci avere notizie! :)

Per chi fosse interessato, ho visto che ha messo le altre date per la prova di programmazione...

Infine, per chi come me fosse prossimo ad affrontare la 2a prova, volevo proporre di condividere gli esercizi più impegnativi che troviamo (o ci vengono in mente) e relative soluzioni da commentare insieme... che ne dite? :D

guarda, cominciamo subito! sto diventando stupido con la clone(), qualcuno mi spiega dove sta il problema?
/*
maggio 2008 prova 1

Il processo padre apre due file in lettura/scrittura (i nomi dei file sono passati sulla riga di comando) e crea due processi clone passando come parametro ad ognuno di essi uno dei file descriptor dei file aperti in precedenza nonchè il byte da scrivere ripetutamente nel file. 

Ognuno dei due clone esegue un ciclo senza fine aspettando un segnale SIGUSR1 dal processo padre. 

Quando riceve tale segnale, il clone scrive 10 byte nel file di sua competenza (il tipo di byte che il clone deve scrivere ed il file descriptor sono passati come parametri della clone() dal processo padre) e si mette in attesa del prossimo segnale. 

Dopo avere creato i due cloni, il processo padre esegue un ciclo per 10 volte consecutive in cui: 

1)calcola con probabilità 1/2 il pid del clone al quale inviare un segnale SIGUSR1 

2)invia al clone avente il pid calcolato in precedenza il segnale SIGUSR1 

3)aspetta 200 msec 

I nomi dei file da creare e i due caratteri che i cloni dovranno scrivere sono passati sulla riga di comando. 

Esempio di riga di comando: prova ./file1 ./file2 a b 
*/

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

#define NPROC 2
#define STACK_SIZE 4096

struct argomenti
{
	int fd;
	char *byte;
};

void handler(int sign)
{
	printf("handler attivato da %d\n", getpid());
	
	return;
}

int cloneFunc(void *args)
{
	signal(SIGUSR1, handler);
	
	int fd = ((struct argomenti *) args)->fd;
	char *byte = ((struct argomenti *) args)->byte;
	
	printf("Creato processo %d, con fd %d e byte %s\n", getpid(), fd, byte);
	
	for ( ; ; )
	{
		pause();
		
		int j;
		for (j = 0; j < 10; j++)
		{
			if (write(fd, byte, 1) < 0)
			{
				printf("Errore in stampa\n");
			}
		}
	
		printf("%d ha eseguito una stampa\n", getpid());
	}
	
	exit(1);
	
	return 1;
}

int main(int argc, char *argv[])
{	
	if (argc != 5)
	{
		printf("Errore nel numero di parametri\nUso: scriviByte2File filename1 filename2 byte1 byte2\n");
		exit(-1);
	}
	
	int i;
	
	struct argomenti *args;
	void *childStack;
	int pid[2];
	int fds[2];
	
	for (i = 0; i < NPROC; i++)
	{	
		if ((fds[i] = creat(argv[i + 1], 0777)) < 0)
		{
			printf("Impossibile creare %s, forse già esiste\n", argv[i + 1]);
			exit(-1);
		}
		
		args = calloc(1, sizeof(struct argomenti));
		
		args->fd = fds[i];
		args->byte = (char *) argv[i + 3];
		
		childStack = calloc(1, STACK_SIZE);				
		
		if ((pid[i] = clone(cloneFunc, childStack, CLONE_FILES, (void *) args)) < 0)
		{
			printf("Errore in clone()\n");
			exit(-1);
		}
		
	}
	
	for (i = 0; i < 10; i++)
	{
		srand(time(NULL));
		int prob = rand() % 2;
		
		kill(pid[prob], SIGUSR1);
		printf("Inviato SIGUSR1 a %d\n", pid[prob]);
		
		usleep(200000);
	}	
	
	for (i = 0; i < NPROC; i++)
	{
		if (kill(pid[i], SIGKILL) < 0)
			printf("Errore in kill %d\n", pid[i]);
			
		//if (close(fds[i]) < 0)
		//	printf("Errore in close %d\n", fds[i]);
	}
	
	exit(1);
}
i 2 file li crea, ma il fd del secondo file lo passa sbagliato e perciò mi segnala un errore di stampa!

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 2 Mesi fa #82674 da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
allora intanto ti do' i seguenti consigli:
1)perche' al padre non fai creare una struct argomenti invece dei puntatori e passi l'indirizzo della struct con &? Il cast da struct argomenti * a void * non so quanto sia corretto, io lo eviterei.. E invece metterei il cast da void* a struct argomenti* all'inizio della clone_func...

2) ERRORE GRAVE è sicuramente il modo in cui chiami la clone().. ogni processo che crei deve avere il suo stack, invece tu ne crei uno solo e oltretutto passi l'indirizzo iniziale anzichè quello finale.. Visto che sai di dover creare solo 2 processi puoi fare come segue senza dover ricorrere all'allocazione dinamica della memoria (questo per rendere le cose + semplici, non perche' sarebbe sbagliato!):

int stackA[1024],stackB[1024];

e poi la clone dovresti chiamarla come

clone (clone_func, &stackA[1023], CLONE_VM|CLONE_FILES,&argA);
idem per B.

Ricorda anche che il flag CLONE_VM è quello che permette ai due figli di condividere lo spazio degli indirizzi col padre... questo è importante specie quando i cloni devono agire sulla stessa variabile globale...

Intanto prova queste modifiche e facci sapere! :)
ciao

PS: Girando su internet e libri vari ho visto che la clone è davvero poco documentata oltre a quello che è scritto nel MAN.. Per vederla in azione l'unica fonte che ho trovato sono stati gli esercizi che sono sul sito di sistemi operativi, che consiglio a tutti....

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 2 Mesi fa #82675 da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
Altra cosa che forse potrebbe darti problemi insidiosi se vorrai fare delle letture sui file: tu li apri usando la creat()... ricorda che "creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC" quindi se vorrai leggere dal file quello che hai scritto dovrai chiudere e riaprire il file con la open (.. O_RDWR...).. :)

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

Di più
17 Anni 2 Mesi fa #82679 da Gabriele
Risposta da Gabriele al topic [LA] Linux avanzato 2008

allora intanto ti do' i seguenti consigli:
1)perche' al padre non fai creare una struct argomenti invece dei puntatori e passi l'indirizzo della struct con &? Il cast da struct argomenti * a void * non so quanto sia corretto, io lo eviterei.. E invece metterei il cast da void* a struct argomenti* all'inizio della clone_func...

2) ERRORE GRAVE è sicuramente il modo in cui chiami la clone().. ogni processo che crei deve avere il suo stack, invece tu ne crei uno solo e oltretutto passi l'indirizzo iniziale anzichè quello finale.. Visto che sai di dover creare solo 2 processi puoi fare come segue senza dover ricorrere all'allocazione dinamica della memoria (questo per rendere le cose + semplici, non perche' sarebbe sbagliato!):

int stackA[1024],stackB[1024];

e poi la clone dovresti chiamarla come

clone (clone_func, &stackA[1023], CLONE_VM|CLONE_FILES,&argA);
idem per B.

Ricorda anche che il flag CLONE_VM è quello che permette ai due figli di condividere lo spazio degli indirizzi col padre... questo è importante specie quando i cloni devono agire sulla stessa variabile globale...

Intanto prova queste modifiche e facci sapere! :)
ciao

PS: Girando su internet e libri vari ho visto che la clone è davvero poco documentata oltre a quello che è scritto nel MAN.. Per vederla in azione l'unica fonte che ho trovato sono stati gli esercizi che sono sul sito di sistemi operativi, che consiglio a tutti....

MITICO! è verissimo, sulla clone() in giro ho trovato pochissimo! infatti l'errore era proprio nel passare lo stack, che doveva essere come hai scritto tu passato con l'ultimo elemento!
CLONE_VM lo evito, perchè non so se bovet accetti l'uso di variabili globali (in teoria andrebbero evitate, e uno che fa tutte quelle storie per mmap()...) perciò passo tutto per parametri, al max con una pipe se serve!
usare i puntatori oppure segli elementi passati con & non cambia, ovviamente funziona uguale! i cast sono giusti, li usavo pure con i pthread per iw! grazie, mi hai salvato dalla follia!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

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