[LA] Linux avanzato 2008
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
17 Anni 2 Mesi fa #82905
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
Altri esercizi di difficoltà leggermente sopra la media quali possono essere? Sparate, sparate.. 
Qualcuno ha notizie sugli orali di ieri?
Qualcuno ha notizie sugli orali di ieri?
Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
17 Anni 2 Mesi fa #82959
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
Allora vi propongo io un altro esercizio:
Che ve ne pare? Mi sembra che sia piuttosto completo come esercizio, no?
Io mi metto a farlo subito dopo aver finito la sys_open senno' non affitto più..
Buon divertimento!
Il programma riceve da riga di comando 2 numeri N e T che rappresentano il numero di cloni che saranno creati e il tempo per cui il loop illustrato di seguito dovrà essere eseguito.
Il processo padre crea dunque N cloni e registra i loro pid in una lista *circolare* avente la seguente struttura:
struct nodo{
struct list_head lh;
pid_t pid
};
struct list_head{
struct list_head *next;
struct list_head *prev;
};
Dunque (sempre il padre) inizia un loop che durerà T secondi durante cui scandirà la lista e:
1) Se tutti i figli sono stati interrogati almeno 1 volta dall'ultima eliminazione, decide con probabilità del 20% di eliminare il figlio corrispondente al nodo scandito.
2) Se il clone corrispondente al nodo deve essere eliminato,gli invia un segnale SIGTERM e poi lo elimina dalla lista, altrimenti lo interroga mediante SIGUSR1.
3) dorme 1 secondo
Se la lista dovesse diventare vuota, il padre stamperà solo "LISTA VUOTA" ad ogni ciclo.
Dal canto loro. i cloni reagiscono solo ai due segnali indicati stampando:
- "PIDX Termina" nel caso gli arrvi un SIGTERM (e dunque terminando la loro esecuzione)
- "PIDX" nel caso gli arrivi un SIGUSR1.
Esempio: N=5 T=20
1 2 3 4 5 1 2 3 Termina 4 5 1 2 4 Termina 5 1 2 5 Termina 1 2 1 2 Termina 1 1 Termina LISTA VUOTA LISTA VUOTA LISTA VUOTA........
NB: Si faccia attenzione a non sprecare memoria.Che ve ne pare? Mi sembra che sia piuttosto completo come esercizio, no?
Io mi metto a farlo subito dopo aver finito la sys_open senno' non affitto più..
Buon divertimento!
Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
17 Anni 2 Mesi fa #82960
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
Dimenticavo una cosa dell'esercizio precedente:
ciao
Trascorsi T secondi, se la lista non è ancora vuota, il padre provvede ad eliminare i figli mediante SIGTERM e a rimuovere i corrispondenti nodi dalla lista. Controllare che nessun processo rimanga nel sistema dopo la terminazione del programma mediante il comando ps.Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
17 Anni 2 Mesi fa #83038
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
Fatto l'orale oggi...tutto ok...Le domande di oggi sono state un pò piu' da ragionamento, es. (ho un modulo, come fa il linker ha sapere l'indirizzo di una printk()).
Cmqe lui è molto tranquillo se vede che hai studiato è assicurata la non bocciatura a differenza di altri che non correggono i progetti perchè non ne capiscono nulla e ti bocciano senza motivo!!!Che dire in bocca al lupo a tutti.....
Cmqe lui è molto tranquillo se vede che hai studiato è assicurata la non bocciatura a differenza di altri che non correggono i progetti perchè non ne capiscono nulla e ti bocciano senza motivo!!!Che dire in bocca al lupo a tutti.....
Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
17 Anni 1 Mese fa #83132
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic [LA] Linux avanzato 2008
Complimentoni dirac!!! 
Posto la soluzione del "mio" esercizio. al solito ogni commento è benvenuto!
ciao
Posto la soluzione del "mio" esercizio. al solito ogni commento è benvenuto!
/*
Il programma riceve da riga di comando 2 numeri N e T che rappresentano il numero di cloni che saranno creati e il tempo per cui il loop illustrato di seguito dovrà essere eseguito.
Il processo padre crea dunque N cloni e registra i loro pid in una lista *circolare* avente la seguente struttura:
struct nodo{
struct list_head lh;
pid_t pid
};
struct list_head{
struct list_head *next;
struct list_head *prev;
};
Dunque (sempre il padre) inizia un loop che durerà T secondi durante cui scandirà la lista e:
1) Se tutti i figli sono stati interrogati almeno 1 volta dall'ultima eliminazione, decide con probabilità del 20% di eliminare il figlio corrispondente al nodo scandito.
2) Se il clone corrispondente al nodo deve essere eliminato,gli invia un segnale SIGTERM e poi lo elimina dalla lista, altrimenti lo interroga mediante SIGUSR1.
3) dorme 1 secondo
Se la lista dovesse diventare vuota, il padre stamperà solo "LISTA VUOTA" ad ogni ciclo.
Dal canto loro. i cloni reagiscono solo ai due segnali indicati stampando:
- "PIDX Termina" nel caso gli arrvi un SIGTERM (e dunque terminando la loro esecuzione)
- "PIDX" nel caso gli arrivi un SIGUSR1.
Esempio: N=5 T=20
1 2 3 4 5 1 2 3 Termina 4 5 1 2 4 Termina 5 1 2 5 Termina 1 2 1 2 Termina 1 1 Termina LISTA VUOTA LISTA VUOTA LISTA VUOTA........
Trascorsi T secondi, se la lista non è ancora vuota, il padre provvede ad eliminare i figli mediante SIGTERM e a rimuovere i corrispondenti
nodi dalla lista. Controllare che nessun processo rimanga nel sistema dopo la terminazione del programma mediante il comando ps.
NB: Si faccia attenzione a non sprecare memoria.
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <wait.h>
#include <sys/types.h>
#include <sched.h>
#include <unistd.h>
#include <time.h>
struct list_head{
struct list_head *next;
struct list_head *prev;
};
typedef struct list_head ListHead;
typedef ListHead *ListHeadPtr;
struct node{
struct list_head lh;
pid_t pid;
};
typedef struct node Node;
typedef Node *NodePtr;
volatile sig_atomic_t sigterm_recipient=0;
volatile sig_atomic_t alarm_expired=0;
int clone_func(void *unused)
{
pid_t my_pid=getpid();
printf("%d IS READY\n",(int)my_pid);
while (1)
{
pause();
if ((pid_t)sigterm_recipient==my_pid)
return 0;
}
}
void sigUSR1handl(int signo)
{
printf("%d\n",(int)getpid());
}
void sigALRMhandl(int signo)
{
printf("TIMER EXPIRED\n");
++alarm_expired;
}
void sigTERMhandl(int signo)
{
sigterm_recipient=(sig_atomic_t)getpid();
printf("%d terminates..\n",(int)sigterm_recipient);
}
int add_node (ListHeadPtr head, pid_t new_pid)
{
NodePtr newnode = malloc(sizeof(Node));
if (newnode==NULL)
{
printf("out of memory\n");
return 0;
}
newnode->pid=new_pid;
(newnode->lh).next=head;
(newnode->lh).prev=head->prev;
head->prev->next=&(newnode->lh);
head->prev=&(newnode->lh);
if (head->next==head) // Is this the first node?
{
head->next=&(newnode->lh);
}
return 1;
}
void print_forward(ListHeadPtr head)
{
if (head->next==head)
{
printf("LIST IS EMPTY\n");
return;
}
ListHeadPtr currPtr;
for (currPtr=head->next; currPtr!=head; currPtr=currPtr->next)
{
printf("%d --> ",(int)((NodePtr)currPtr)->pid);
}
printf(" END\n");
}
void delete_node (ListHeadPtr head, NodePtr node)
{
((node->lh).prev)->next = (node->lh).next;
((node->lh).next)->prev = (node->lh).prev;
free(node);
}
int list_is_empty(ListHeadPtr head)
{
return (head->next==head);
}
void init_list(ListHeadPtr head)
{
head->next=head;
head->prev=head;
}
int main (int argc, char *argv[])
{
if (argc!=3)
{
printf("Usage Num_Processes Timer\n");
return 1;
}
int i;
//Init list
ListHead head;
init_list(&head);
int n=atoi(argv[1]);
int t=atoi(argv[2]);
pid_t pid;
int *stack_clones = malloc(sizeof(int)*1024*n);
if(stack_clones==NULL)
{
printf("OUT OF MEMORY\n");
return 1;
}
//Register signal handlers
struct sigaction sa_USR1 = { .sa_handler=sigUSR1handl};
sigaction (SIGUSR1,&sa_USR1, NULL);
struct sigaction sa_TERM = { .sa_handler=sigTERMhandl};
sigaction (SIGTERM,&sa_TERM, NULL);
for (i=0;i<n;i++)
{
if ( (pid=clone(clone_func, stack_clones+( (i+1)*1024 ), CLONE_VM|CLONE_SIGHAND, NULL)) < 0)
{
printf("BAD CLONE\n");
return 1;
}
if (add_node(&head,pid)<1)
{
printf("BAD add_node()\n");
return 1;
}
}
//The list is now ready, we have just a few other actions to perform before entering the main loop
struct sigaction sa_ALRM= { .sa_handler=sigALRMhandl};
sigaction (SIGALRM,&sa_ALRM, NULL);
srand(time(NULL));
ListHeadPtr cycleBeginPtr,currPtr,tmpPtr;
int prob,sigterm_allowed=0;
printf("THIS IS THE STARTING LIST: "); print_forward(&head);
sleep(1);
alarm(t); //Ask to be notified in t secs
for (currPtr=head.next,cycleBeginPtr=head.next; !alarm_expired; ) //infinite loop over the list
{
sleep(1);
if (list_is_empty(&head))
{
printf("LIST IS EMPTY\n");
continue;
}
prob=101;
if (sigterm_allowed)
{
prob=rand()%100+1;//prob ranges from 1 to 100
}
if (prob<=20) //1-20 range = 20%
{
kill( ((NodePtr)currPtr)->pid ,SIGTERM );
pid=waitpid(((NodePtr)currPtr)->pid,0,__WCLONE);
if (pid<0)
{
printf("BAD WAITPID\n");
//return 1;
}
tmpPtr=currPtr->next;
if (tmpPtr==&head) //I deleted the last node
{
currPtr=head.next;
}
/*
NOTE: it may happen that the list is now empty and currPtr points again to head.
This is not a problem and will be detected at the next round. Remember that this list can just shrink!
*/
sigterm_allowed=0;
delete_node(&head,(NodePtr)currPtr);
currPtr=tmpPtr;
cycleBeginPtr=currPtr;
continue;
}
kill( ((NodePtr)currPtr)->pid, SIGUSR1);
currPtr=currPtr->next;
if (currPtr==&head) //I polled the last node
{
currPtr=head.next;
}
if (currPtr==cycleBeginPtr) //I did a complete walk over the list since the last sigterm. From now on I can use sigterm
{
sigterm_allowed=1;
}
}
if (!list_is_empty(&head))
{
printf("I have to empty the list\n");
for (currPtr=head.next;currPtr!=&head;)
{
kill( ((NodePtr)currPtr)->pid ,SIGTERM );
pid=waitpid(((NodePtr)currPtr)->pid,0,__WCLONE);
if (pid<0)
{
printf("BAD WAITPID\n");
//return 1;
}
tmpPtr=currPtr->next;
delete_node(&head,(NodePtr)currPtr);
currPtr=tmpPtr;
}
}
printf("END\n");
return 0;
}Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
17 Anni 1 Mese fa #83148
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?
Si prega Accedi o Crea un account a partecipare alla conversazione.