Difference between revisions of "SYS CALL viste a lezione."

From Sistemi Operativi
Jump to navigation Jump to search
Line 112: Line 112:
 
printf(" padre : %d  figlio : %d \n",getpid(),pid);
 
printf(" padre : %d  figlio : %d \n",getpid(),pid);
 
                 sleep(10);  
 
                 sleep(10);  
waitpid(pid,status,0);
+
waitpid(pid,&status,0);
 
printf(" exit status %d \n",WEXITSTATUS(status)); //Macro che restituisce l' exit status del figlio,cioè gli otto bit meno significativi dello status che il figlio
 
printf(" exit status %d \n",WEXITSTATUS(status)); //Macro che restituisce l' exit status del figlio,cioè gli otto bit meno significativi dello status che il figlio
 
}                                                        //specifica in una chiamata di _exit o exit o come argomento di ritorno del main.
 
}                                                        //specifica in una chiamata di _exit o exit o come argomento di ritorno del main.
Line 138: Line 138:
 
printf(" padre : %d  figlio : %d \n",getpid(),pid);
 
printf(" padre : %d  figlio : %d \n",getpid(),pid);
 
sleep(5);
 
sleep(5);
waitpid(pid,status,0);
+
waitpid(pid,&status,0);
 
if (WIFEXITED(status)) //Macro che restituisce true se il figlio termina normalmente, cioé chiamando _exit o exit oppure tramite il return del main
 
if (WIFEXITED(status)) //Macro che restituisce true se il figlio termina normalmente, cioé chiamando _exit o exit oppure tramite il return del main
 
printf(" exit status %d \n", WEXITSTATUS(status));
 
printf(" exit status %d \n", WEXITSTATUS(status));
Line 174: Line 174:
 
printf(" padre : %d  figlio : %d \n",getpid(),pid);
 
printf(" padre : %d  figlio : %d \n",getpid(),pid);
 
sleep(5);
 
sleep(5);
waitpid(pid,status,0);
+
waitpid(pid,&status,0);
 
if (WIFEXITED(status))  
 
if (WIFEXITED(status))  
 
printf(" exit status %d \n", WEXITSTATUS(status));
 
printf(" exit status %d \n", WEXITSTATUS(status));
Line 186: Line 186:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
esempio2:
 +
<syntaxhighlight lang="C">
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <stdlib.h>
 +
#include <sys/types.h>
 +
#include <sys/wait.h>
 +
 +
int main (int argc, char *argv[]){
 +
pid_t pid;
 +
if( pid = fork() ){
 +
int status;
 +
printf(" padre : %d  figlio : %d %s \n",getpid(),pid,argv[1]);
 +
sleep(5);
 +
waitpid(pid,&status,0);
 +
if (WIFEXITED(status))
 +
printf(" exit status %d \n", WEXITSTATUS(status));
 +
else if( WIFSIGNALED(status) ) 
 +
printf("signal : %d \n", WTERMSIG(status) );
 +
}
 +
else {
 +
execvp(argv[2],argv+2);
 +
}
 +
}
 +
</syntaxhighlight>
 +
  
 
Correggetemi se ho scritto delle sciocchezze.
 
Correggetemi se ho scritto delle sciocchezze.
 
(Pirata)
 
(Pirata)

Revision as of 12:03, 10 November 2013

  • FORK

Crea un nuovo processo duplicando il processo chiamante. Il nuovo processo , chiamato figlio, é un duplicato esatto del processo chiamante , chiamato padre.

esempio1:

#include <stdio.h>
#include <unistd.h>

void main (void){     
	if(fork()){
	printf("uno  %d  %d \n", getpid(), getppid() ); // getpid() stampa il pid del processo corrente , getppid() stampa il pid del processo padre
        sleep(2);}   //se togliessimo lo sleep;il processo figlio stamperebbe come getppid() 1,perché essendo il padre terminato e lui rimasto orfano,il nuovo padre diventa init
	else
	printf("due %d %d  \n",getpid(), getppid() );
}

esempio2(una piccola osservazione sull'eredità del buffer):

#include <stdio.h>
#include <unistd.h>

void main (void){
	printf("cucù! : ");      //notare la differenza se nella sringa metto \n 
	if(fork())
	printf("uno  %d  %d \n", getpid(), getppid() );
	else
	printf("due %d %d  \n",getpid(), getppid() );
}

esempio3(fork e malloc):
(sottolineerei che lo spazio di indirizzamento è di fatto separato: i due processi hanno una analoga visione dell'indirizzamento logico, che però è specifico di ogni processo e i dati sono memorizzati fisicamente in aree di memoria diverse. am_20131110)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


void main (void){
	int *p;
	if( fork() ){
	p = malloc(sizeof(int));
	*p = 45;
	printf("%d %p  pid : %d  , ppid : %d \n",*p,p,getpid(),getppid());   
	sleep(2);
	}
	else {
	p = malloc(sizeof(int));
	printf("%d %p  pid : %d  , ppid : %d \n",*p,p,getpid(),getppid());  //i puntatori restituiranno lo stesso indirizzo di memoria sia per il padre che per il figlio         
	sleep(1);                                                           //perché condividono lo stesso spazio di indirizzamento
	}
}


  • _EXIT

Termina il proceso chiamante.

esempio1:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main (int argc,char *argv[]){
	_exit(0);                     //Sys call che termina il processo chiamante
}

esempio2(atexit):

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void at1(void){
	printf("at1 \n");
	}

void at2(void){
	printf("at2 \n");
	}


int main (int argc,char *argv[]){
	printf("brutal kill \n");
	atexit(at1);	//funzione di libreria che termina il processo passato come argomento
	atexit(at2); 
}

//le funzioni passate ad atexit vengono eseguite in modo inverso rispetto all'invocazione


  • WAIT

Aspetta che un processo cambi di stato.

esempio1:

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

int main (int argc, char *argv[]){
	pid_t pid;
	if( pid = fork() ){
		int status;
		printf(" padre : %d  figlio : %d \n",getpid(),pid);
                sleep(10); 
		waitpid(pid,&status,0);
		printf(" exit status %d \n",WEXITSTATUS(status)); //Macro che restituisce l' exit status del figlio,cioè gli otto bit meno significativi dello status che il figlio
	}                                                         //specifica in una chiamata di _exit o exit o come argomento di ritorno del main.
	else {
		printf(" figlio : %d  padre : %d \n",getpid(),getppid());
		sleep(1);
		exit(1);
		}
}


esempio2:

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

int main (int argc, char *argv[]){
	pid_t pid;
	if( pid = fork() ){
		int status;
		printf(" padre : %d  figlio : %d \n",getpid(),pid);
		sleep(5);
		waitpid(pid,&status,0);
		if (WIFEXITED(status)) //Macro che restituisce true se il figlio termina normalmente, cioé chiamando _exit o exit oppure tramite il return del main
		printf(" exit status %d \n", WEXITSTATUS(status));
		else if(WIFSIGNALED(status) )  //Macro che restituisce true se il figlio é terminato da un segnale
			printf("signal : %d \n", WTERMSIG(status) );  //Macro che restituisce il numero del segnale che causa la terminazione del processo figlio
	}
	else {
		int *p;
		printf(" figlio : %d  padre : %d \n",getpid(),getppid());
		sleep(1);
		p = (int *)42;
		*p = 43;	
		exit(2);
		}
}


  • EXECVE

Esegue un programma. La famiglia di funzioni exe() rimpiazza l'immagine del processo corrente con l'immagine di un nuovo processo.

esempio1:

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

int main (int argc, char *argv[]){
	pid_t pid;
	if( pid = fork() ){
		int status;
		printf(" padre : %d  figlio : %d \n",getpid(),pid);
		sleep(5);
		waitpid(pid,&status,0);
		if (WIFEXITED(status)) 
		printf(" exit status %d \n", WEXITSTATUS(status));
		else if( WIFSIGNALED(status) )  
			printf("signal : %d \n", WTERMSIG(status) ); 
	}
	else {
		char *args[] = {"ls","-l",(char *)0};
		execvp("ls",args); //funzione di libreria che prende in input il path(p) e un vettore(v).
	}
}

esempio2:

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

int main (int argc, char *argv[]){
	pid_t pid;
	if( pid = fork() ){
		int status;
		printf(" padre : %d  figlio : %d %s \n",getpid(),pid,argv[1]);
		sleep(5);
		waitpid(pid,&status,0);
		if (WIFEXITED(status)) 
		printf(" exit status %d \n", WEXITSTATUS(status));
		else if( WIFSIGNALED(status) )  
			printf("signal : %d \n", WTERMSIG(status) ); 
	}
	else {
		execvp(argv[2],argv+2);
	}
}


Correggetemi se ho scritto delle sciocchezze. (Pirata)