ProvaPratica 2013.05.29
Jump to navigation
Jump to search
Esercizio 1
Scrivere un programma testeventfd che faccia uso della system call eventfd.
In particolare il programma deve eseguire una fork, quando l'utente digita un numero letto dal processo padre, il processo
figlio deve stampare un numero uguale di x.
$ testeventfd
3
x
x
x
2
x
x
Soluzione di GiuliaN.
#include <sys/eventfd.h>
#include <stdio.h>
#include <unistd.h>
#define BUFFSIZE 10
int main(int argc, char *argv[]){
int efd,n,i;
char buf1[BUFFSIZE];
char buf2[BUFFSIZE];
do{
efd = eventfd(0,0);
}while(efd<0);
while(1){
if(fork()){ /*padre*/
read(0,buf1,sizeof(buf1)); /*0 indica lo standard input*/
write(efd, buf1, sizeof(buf1));
}
else{ /*figlio*/
read(efd, buf2, sizeof(buf2));
n=atoi(buf2);
for(i=0; i<n; i++) printf("x\n");
}
}
}
GiuliaN. con grande aiuto da parte dei colleghi
Soluzione del Prof. Davoli
(visto a lezione , soluzione del Prof. Davoli ricopiata da Pirata_20131203)
#include <sys/eventfd.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFSIZE 10
int main(int argc, char *argv[]){
int efd , n , i;
uint64_t a , b;
if ( ( efd = eventfd( 0 , EFD_SEMAPHORE ) ) < 0 )
exit( 1 );
if ( fork() > 0 ){
while ( 1 ) {
uint64_t a;
scanf( "%lld" , &a );
write( efd , &a , sizeof( a ) );
}
}
else {
while ( 1 ) {
uint64_t b;
read( efd , &b , sizeof( b ) );
printf( "x\n" );
}
}
}
Soluzione di Pierg
#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
int main (int argc, char *argv[]) {
int efd, i;
long long unsigned int val;
ssize_t s;
/* Check for eventfd error */
efd = eventfd(0, 0);
if (efd == -1) {
perror("Eventfd Error");
}
/* Use fork to move eventfd form parent to child */
switch (fork()) {
case 0:
/* Read parent event */
s = read(efd, &val, sizeof(long long unsigned int));
if (s != sizeof(long long unsigned int)) {
perror("Read Error");
exit(EXIT_FAILURE);
}
/* For is used to print the 'x' of the argument passed by terminal */
for (i = (int)val; i > 0; i--) {
printf ("x\n");
}
exit(EXIT_SUCCESS);
/* Check for error */
case -1:
perror("Fork Error");
exit(EXIT_FAILURE);
default:
/* Wait for number */
printf ("Inserisci un intero diverso da 0: \n");
scanf ("%llu", &val);
/* Write parent event */
s = write(efd, &val, sizeof(long long unsigned int));
if (s != sizeof(long long unsigned int)) {
perror("Write Error");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
}
Soluzione di Maldus
Semaforo implementato usando un altro eventfd.
#include <stdio.h>
#include <sys/eventfd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <signal.h>
int main(){
pid_t son ;
int ed1 , ed2 , i;
uint64_t x = 1;
int y = 1 ;
ed1 = eventfd(0,0) ; /*eventfd usato per la comunicazione effettiva del numero*/
ed2 = eventfd( 1 , EFD_SEMAPHORE ) ; /*eventfd usato come semaforo*/
switch( son = fork() ){
case 0:
while( 1 ){
read( ed1 , &x , 8) ; /*se ci sono dei dati li legge*/
for(i = x ; i > 0 ; i--) printf( "x" ) ;
printf("\n");
write(ed2 , &y , 8 ) ; /*dopo la lettura dei dati, dà il via libera sul semaforo per scrivere di nuovo*/
}
return 1;
default:
while( x ){
read( ed2 , &y , 8 ) ; /*si blocca sul semaforo se i dati non sono ancora stati letti*/
scanf("%" PRIu64 , &x) ;
write(ed1 , &x , 8 ) ; /*scrittura dei dati*/
}
kill(son ,SIGTERM);
return 0 ;
}
}
Esercizio 2
Soluzione di Eduardo Santarelli
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/eventfd.h>
#define SIZE 64
int main(int argc, char **argv){
int efd_parent, efd_child;
pid_t pid;
efd_parent = eventfd(0, 0);
efd_child = eventfd(0, 0);
pid = fork();
if(pid < 0){
perror("Fork error. ");
exit(EXIT_FAILURE);
}
/* parent */
if(pid){
int okToWrite = 1;
ssize_t n;
char buf[SIZE];
for(;;){
if(okToWrite){
scanf("%s", buf);
n = write(efd_parent, buf, SIZE);
if(n < 0){
perror("Parent: write error.");
exit(EXIT_FAILURE);
}
okToWrite = 1-okToWrite;
}
else{
n = read(efd_child, buf, SIZE);
if( n < sizeof(uint64_t) ){
printf("Parent: something bad happened");
exit(EXIT_FAILURE);
}
printf("padre: %s\n", buf);
okToWrite = 1-okToWrite;
}
}
close(efd_parent);
}
/* child */
else{
int okToWrite = 0;
char buf[SIZE];
int n;
for(;;){
if(okToWrite){
scanf("%s", buf);
n = write(efd_child, buf, SIZE);
if(n < 0){
perror("child: write error.");
exit(EXIT_FAILURE);
}
okToWrite = 1-okToWrite;
}
else{
n = read(efd_parent, buf, SIZE);
if( n < sizeof(uint64_t) ){
printf("Child: something bad happened");
exit(EXIT_FAILURE);
}
printf("figlio: %s\n", buf);
okToWrite = 1-okToWrite;
}
}
close(efd_child);
}
return EXIT_SUCCESS;
}
- Eduardo
Esercizio 3
===Soluzione di Tommaso Ognibene(Python 3)
'''
Prova Pratica di Laboratorio di Sistemi Operativi
29 maggio 2013
Esercizio 3
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.05.29.pdf
@author: Tommaso Ognibene
'''
import os, sys
def Main(argv):
# Check number of arguments
if len(argv) != 2:
print("The function requires one argument to be passed in.")
return
# Check parameters
topDir = str(sys.argv[1])
if not os.path.isdir(topDir):
print("The parameter should be an existing directory.")
return
# Build a dictionary with key-value pair {file extension - total size}
extensionSize = { }
GetSize(topDir, extensionSize)
# Print results
PrintResults(extensionSize)
def GetSize(topDir, extensionSize):
for dirPath, dirNames, files in os.walk(topDir):
for file in files:
# 'example.mp3' -> ['example', 'mp3']
# 'example.tar.gz' -> ['example', 'tar', 'gz']
parts = file.split('.')
# ['example', 'mp3'] -> ['mp3']
# ['example', 'tar', 'gz'] -> ['tar', 'gz']
parts = parts[1:]
# ['mp3'] -> '.mp3'
# ['tar', 'gz'] -> '.tar.gz'
fileExtension = ".{0}".format(".".join(str(part) for part in parts))
# Compute the size in Bytes and update the dictionary
filePath = os.path.join(dirPath, file)
fileSize = os.path.getsize(filePath)
extensionSize[fileExtension] = extensionSize.get(fileExtension, 0) + fileSize
# Print results
def PrintResults(extensionSize):
for key, value in sorted(extensionSize.items()):
print('{0}: {1} Bytes.'.format(key, value))
if __name__ == "__main__":
sys.exit(Main(sys.argv))
Soluzione di Fede(python 3)
import os, sys, copy
def dotsubstr(a):#restituisce la sottostringa .suffisso
#fcd = os.listdir('{0}'.format(arg1))
i=0
try:
while a[i]!='.':
i=i+1
return a[i:]
except IndexError:
return -1
def compliarg(li,arg):#restituisce una lista di tutti gli elementi contenenti la sottostringa arg come suffisso
res=[]
while li != []:
a=li.pop()
if a.endswith(arg): res.append(a)
return res
def listremintsect(l2,l1):#restituisce una lista res = l1 - intersezione di l1 ed l2
res=[]
while l1 != []:
a=l1.pop()
if not a in l2: res.append(a)
return res
def createpathlist(c,path):#restituisce una lista di path 'path' relativi ai file contenuti in c.
res = []
while c != []:
res.append('{0}/{1}'.format(path,c.pop()))
return res
def totsizes(d): #data una lista d di path restituisce la somma di tutti i size di d
res = 0
while d != []:
a = d.pop()
if os.path.isfile('{0}'.format(a)):
res = res + os.path.getsize('{0}'.format(a))
return res
def listsubstr(arg): #ritorna un dizionario del tipo diz[str(suffisso)] = int(size relativo al suffisso)
res = {}
fcd = os.listdir('{0}'.format(arg))
while fcd != []:
fcdtmp=copy.deepcopy(fcd) #BUGGONE SENZA COPY!!!!!!
a = fcd.pop()
b = dotsubstr(a)
if b == -1: continue
else: pass
c = compliarg(fcdtmp,b)
s=copy.deepcopy(c) #!!!!!!!!!!!!!!!!!!!!!!!!!
d = createpathlist(c,arg)
res[b] = totsizes(d)
fcd = listremintsect(s,fcd)
return res
try:
res = listsubstr(sys.argv[1])
a=list(res.keys())
while a != []:
b = a.pop()
print('{0}:\t{1}'.format(b,res[b]))
except OSError:
print("Could not solve path")
Soluzione in bash(Pirata & Fede)
#! /bin/bash
for f in "$1"/*.* ; do
somma=0
ext=${f##*.}
for file in *."$ext"
do
somma=$(expr $somma + $(stat -c%s "$file"))
done
echo -n "size of file with extension "$ext" : "
echo "$somma"
done
Per (Pirata & Fede) -Bash-: ci siamo quasi...però forse rifate gli stessi calcoli un po' di volte in più del necessario ;-) (am_20131127).
Soluzione di Eduardo Santarelli (python)
#!/usr/bin/env python3
#
# Prova Pratica di Lab SO 2013.05.29
# Es. 3
# Eduardo Santarelli
#####################################
import os, sys
# return the suffix of file named fname, if present.
# return boolean value False otherwise
def get_suffix(fname):
if '.' in fname:
separator = fname.find('.')
return fname[separator : ]
else:
return False
# Place a file in a dictionary. Each key corresponds
# to a specific suffix, its value is a list of all the
# file with that suffix
def build_dict(item, suffix):
if suffix in all_files:
all_files[suffix].append(item)
else:
all_files[suffix] = []
all_files[suffix].append(item)
# For each suffix key in the dictionary,
# calculates the total size of the files
# in the corresponding list
def size_of_entry(file_list):
size = 0
for item in file_list:
size += os.path.getsize(item)
return size
# This dictionary will contain a key for each suffix,
# associated with a list of all the files ending with
# that suffix
all_files = dict()
# Go to target directory and build a list containing all filenames
try:
target_dir = sys.argv[1]
except:
target_dir = '.'
os.chdir(target_dir)
dir_list = os.listdir('.')
# For each file call get_suffix and then build_dict
# (unless get_suffix returns False)
for item in dir_list:
suffix = get_suffix(item)
if not suffix:
pass
else:
build_dict(item, suffix)
for key in all_files :
print("{0}: {1} Bytes".format(key, size_of_entry(all_files[key])))
-Eduardo --edit: dir_list = os.listdir(target_dir) non funzionava bene coi path relativi. Ora os.listdir('.') dovrebbe andare bene.