Difference between revisions of "ProvaPratica 2011.05.30"
Jump to navigation
Jump to search
(Created page with "[http://www.cs.unibo.it/~renzo/so/pratiche/2011.05.30.pdf Link to exam] Esercizio 1 sender.c <syntaxhighlight lang="C"> #include <stdlib.h> #include <stdio.h> #include <un...") |
(Aggiunta soluzione es 1) |
||
| (2 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
[http://www.cs.unibo.it/~renzo/so/pratiche/2011.05.30.pdf Link to exam] | [http://www.cs.unibo.it/~renzo/so/pratiche/2011.05.30.pdf Link to exam] | ||
| − | Esercizio 1 | + | ==Esercizio 1== |
| − | + | <source lang="text"> | |
| − | + | Scrivere due programmi in modo che i parametri passati al | |
| + | primo vengano stampati dal secondo. La comunicazione deve avvenire tramite una shared memory realizzata | ||
| + | con la chiamata POSIX shm_open, la sincronizzazione tramite segnali. Viene attivato per primo il programma | ||
| + | ricevente. (anche i pid dei processi possono venir scambiati attraverso la shared memory!). | ||
| + | Es: scrivere in un terminale: | ||
| + | $./receiver | ||
| + | l'esecuzione di “receiver rimane in attesa”. in un secondo terminale scrivere: | ||
| + | $./sender a bb ccc | ||
| + | nel primo deve comparire | ||
| + | ./sender | ||
| + | a | ||
| + | bb | ||
| + | ccc | ||
| + | </source> | ||
| + | ===Soluzione di Gab=== | ||
sender.c | sender.c | ||
| Line 101: | Line 115: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
| + | Gab | ||
| + | ===Soluzione di Dado e Pierg=== | ||
| + | |||
| + | sender.c | ||
| + | <source lang="c"> | ||
| + | #include <stdio.h> | ||
| + | #include <stdlib.h> | ||
| + | #include <sys/mman.h> | ||
| + | #include <sys/stat.h> | ||
| + | #include <fcntl.h> | ||
| + | |||
| + | int main(int argc, char * argv[]){ | ||
| + | int fd,i; | ||
| + | fd=shm_open("/shared",O_RDWR,'w'); | ||
| + | if(fd==-1){ | ||
| + | fprintf(stderr,"Error while opening the shared memory\n"); | ||
| + | } | ||
| + | for(i=0;i<argc;i++){ | ||
| + | write(fd,argv[i],sizeof(argv[i])); | ||
| + | write(fd,"\n",1); | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | receiver.c | ||
| + | <source lang="c"> | ||
| + | #include <stdio.h> | ||
| + | #include <stdlib.h> | ||
| + | #include <sys/mman.h> | ||
| + | #include <sys/stat.h> | ||
| + | #include <fcntl.h> | ||
| + | #define MAXLENGTH 1024 | ||
| + | |||
| + | int main(int argc, char * argv[]){ | ||
| + | int fd; | ||
| + | ssize_t dim; | ||
| + | char buff[MAXLENGTH]; | ||
| + | fd=shm_open("/shared",O_RDWR,'r'); | ||
| + | while((dim=read(fd,&buff,MAXLENGTH))){ | ||
| + | write(stdout,buff,MAXLENGTH); | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </source> | ||
| + | Manca la sincronizzazione tramite segnali --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 16:33, 27 May 2017 (CEST) | ||
| + | |||
| + | ===Soluzione di FedericoB=== | ||
| + | receiver | ||
| + | <source lang="C"> | ||
| + | #define _GNU_SOURCE | ||
| + | |||
| + | #include <stdlib.h> | ||
| + | #include <stdio.h> | ||
| + | #include <unistd.h> | ||
| + | #include <sys/mman.h> | ||
| + | #include <sys/stat.h> | ||
| + | #include <signal.h> | ||
| + | #include <fcntl.h> | ||
| + | #include <string.h> | ||
| + | |||
| + | #define MAXSIZE 4096 | ||
| + | |||
| + | int main(int argc, char* argv[]) { | ||
| + | int sharedFD; | ||
| + | printf("pid = %d\n", getpid()); | ||
| + | //create shared memory object | ||
| + | if ((sharedFD = shm_open("/sharedPID", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) != -1) { | ||
| + | //set size of shared memory object | ||
| + | if (ftruncate(sharedFD, MAXSIZE) == 0) { | ||
| + | //create a memory mapping with sharedVariable and the shared memory object | ||
| + | #define OFFSET 0 | ||
| + | #define ADDRESS NULL | ||
| + | char* sharedVariable = mmap(ADDRESS, MAXSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, sharedFD, OFFSET); | ||
| + | if (sharedVariable != MAP_FAILED) { | ||
| + | sprintf(sharedVariable, "%d\n", getpid()); | ||
| + | sigset_t mask; | ||
| + | //initialize signal mask | ||
| + | sigemptyset(&mask); | ||
| + | sigaddset(&mask, SIGUSR1); | ||
| + | //block default handler for SIGUSR1 | ||
| + | sigprocmask(SIG_BLOCK, &mask, NULL); | ||
| + | int sig; | ||
| + | //wait for a SIGURS1 | ||
| + | sigwait(&mask, &sig); | ||
| + | printf("%s\n", sharedVariable); | ||
| + | shm_unlink("/sharedPID"); | ||
| + | return 0; | ||
| + | } else { | ||
| + | perror(NULL); | ||
| + | } | ||
| + | } else { | ||
| + | perror(NULL); | ||
| + | } | ||
| + | } else { | ||
| + | perror(NULL); | ||
| + | } | ||
| + | |||
| + | } | ||
| + | </source> | ||
| + | sender | ||
| + | <source lang="c"> | ||
| + | #include <stdlib.h> | ||
| + | #include <stdio.h> | ||
| + | #include <unistd.h> | ||
| + | #include <sys/mman.h> | ||
| + | #include <sys/stat.h> | ||
| + | #include <fcntl.h> | ||
| + | #include <string.h> | ||
| + | #include <signal.h> | ||
| + | |||
| + | #define MAXSIZE 4096 | ||
| + | |||
| + | int main(int argc,char *argv[]) { | ||
| + | int sharedFD; | ||
| + | //create shared memory object | ||
| + | if ((sharedFD = shm_open("/sharedPID", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) != -1) { | ||
| + | ftruncate(sharedFD, MAXSIZE); | ||
| + | #define OFFSET 0 | ||
| + | #define ADDRESS NULL | ||
| + | char* sharedVariable = mmap(ADDRESS, MAXSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, sharedFD, OFFSET); | ||
| + | int effectivePID = atoi(sharedVariable); | ||
| + | printf("pid = %d\n",effectivePID); | ||
| + | shm_unlink("/sharedPID"); | ||
| + | int i; | ||
| + | for (i=0;i<MAXSIZE;i++) sharedVariable[i]='\0'; | ||
| + | for (i = 1; i < argc; i++) { | ||
| + | strcat(sharedVariable, argv[i]); | ||
| + | strcat(sharedVariable, " "); | ||
| + | } | ||
| + | kill(effectivePID, SIGUSR1); | ||
| + | return 0; | ||
| + | } else { | ||
| + | perror(NULL); | ||
| + | } | ||
| + | } | ||
| + | </source> | ||
Latest revision as of 16:33, 27 May 2017
Esercizio 1
Scrivere due programmi in modo che i parametri passati al
primo vengano stampati dal secondo. La comunicazione deve avvenire tramite una shared memory realizzata
con la chiamata POSIX shm_open, la sincronizzazione tramite segnali. Viene attivato per primo il programma
ricevente. (anche i pid dei processi possono venir scambiati attraverso la shared memory!).
Es: scrivere in un terminale:
$./receiver
l'esecuzione di “receiver rimane in attesa”. in un secondo terminale scrivere:
$./sender a bb ccc
nel primo deve comparire
./sender
a
bb
ccc
Soluzione di Gab
sender.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#define COMMUNICATION_SIGNAL 25
#define MAXIMUM_LENGTH 4096
#define PID_LENGTH 10
int main(int argc,char *argv[])
{
int sharedFD = shm_open("/sharedPID", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if(!sharedFD)
return;
ftruncate(sharedFD,sizeof(char)*PID_LENGTH);
char *sharedVariable = mmap(NULL,sizeof(char)*PID_LENGTH,PROT_READ | PROT_WRITE,MAP_SHARED,sharedFD,0);
int effectivePID = atoi(sharedVariable);
int sharedParametersFD = shm_open("/sharedParameters", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if(!sharedParametersFD)
return;
ftruncate(sharedParametersFD,sizeof(char)*MAXIMUM_LENGTH);
char *parameters = mmap(NULL,sizeof(char)*MAXIMUM_LENGTH,PROT_READ | PROT_WRITE,MAP_SHARED,sharedParametersFD,0);
char parametersToPass[MAXIMUM_LENGTH];
int i;
for(i=0;i<MAXIMUM_LENGTH;i++)
parametersToPass[i]='\0';
for(i=0;i<argc;i++)
{
strcat(parametersToPass,argv[i]);
strcat(parametersToPass,"\n");
}
strcpy(parameters,parametersToPass);
kill(effectivePID,COMMUNICATION_SIGNAL);
return 0;
}
receiver.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#define COMMUNICATION_SIGNAL 25
#define MAXIMUM_LENGTH 4096
#define PID_LENGTH 10
static void signalHandler (int sig, siginfo_t *siginfo, void *context)
{
int sharedFD = shm_open("/sharedParameters", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if(!sharedFD)
return;
ftruncate(sharedFD,sizeof(char)*MAXIMUM_LENGTH);
char *parameters = mmap(NULL,sizeof(char)*MAXIMUM_LENGTH,PROT_READ | PROT_WRITE,MAP_SHARED,sharedFD,0);
printf("Parameters: %s",parameters);
exit(0);
}
int main(int argc,char *argv[])
{
int sharedFD = shm_open("/sharedPID", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if(!sharedFD)
return;
char *currentPIDToPass;
asprintf(¤tPIDToPass,"%d",getpid());
ftruncate(sharedFD,sizeof(char)*PID_LENGTH);
char *sharedVariable = mmap(NULL,sizeof(char)*PID_LENGTH,PROT_READ | PROT_WRITE,MAP_SHARED,sharedFD,0);
strcpy(sharedVariable,currentPIDToPass);
struct sigaction signalStruct;
signalStruct.sa_sigaction = &signalHandler;
sigaction(COMMUNICATION_SIGNAL,&signalStruct,NULL);
while(1){}
return 0;
}
Gab
Soluzione di Dado e Pierg
sender.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char * argv[]){
int fd,i;
fd=shm_open("/shared",O_RDWR,'w');
if(fd==-1){
fprintf(stderr,"Error while opening the shared memory\n");
}
for(i=0;i<argc;i++){
write(fd,argv[i],sizeof(argv[i]));
write(fd,"\n",1);
}
return 0;
}
receiver.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAXLENGTH 1024
int main(int argc, char * argv[]){
int fd;
ssize_t dim;
char buff[MAXLENGTH];
fd=shm_open("/shared",O_RDWR,'r');
while((dim=read(fd,&buff,MAXLENGTH))){
write(stdout,buff,MAXLENGTH);
}
return 0;
}
Manca la sincronizzazione tramite segnali --FedericoB (talk) 16:33, 27 May 2017 (CEST)
Soluzione di FedericoB
receiver
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#define MAXSIZE 4096
int main(int argc, char* argv[]) {
int sharedFD;
printf("pid = %d\n", getpid());
//create shared memory object
if ((sharedFD = shm_open("/sharedPID", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) != -1) {
//set size of shared memory object
if (ftruncate(sharedFD, MAXSIZE) == 0) {
//create a memory mapping with sharedVariable and the shared memory object
#define OFFSET 0
#define ADDRESS NULL
char* sharedVariable = mmap(ADDRESS, MAXSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, sharedFD, OFFSET);
if (sharedVariable != MAP_FAILED) {
sprintf(sharedVariable, "%d\n", getpid());
sigset_t mask;
//initialize signal mask
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
//block default handler for SIGUSR1
sigprocmask(SIG_BLOCK, &mask, NULL);
int sig;
//wait for a SIGURS1
sigwait(&mask, &sig);
printf("%s\n", sharedVariable);
shm_unlink("/sharedPID");
return 0;
} else {
perror(NULL);
}
} else {
perror(NULL);
}
} else {
perror(NULL);
}
}
sender
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#define MAXSIZE 4096
int main(int argc,char *argv[]) {
int sharedFD;
//create shared memory object
if ((sharedFD = shm_open("/sharedPID", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) != -1) {
ftruncate(sharedFD, MAXSIZE);
#define OFFSET 0
#define ADDRESS NULL
char* sharedVariable = mmap(ADDRESS, MAXSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, sharedFD, OFFSET);
int effectivePID = atoi(sharedVariable);
printf("pid = %d\n",effectivePID);
shm_unlink("/sharedPID");
int i;
for (i=0;i<MAXSIZE;i++) sharedVariable[i]='\0';
for (i = 1; i < argc; i++) {
strcat(sharedVariable, argv[i]);
strcat(sharedVariable, " ");
}
kill(effectivePID, SIGUSR1);
return 0;
} else {
perror(NULL);
}
}