luni, 16 aprilie 2007

class="MsoNormal" style="">Pr.20 Să se scrie un program care elimină tot al cincilea octet dintr-un fiş, fără a se folosi un

fişier temporar sau fără a aloca un buffer în memorie de dimensiunea fiş

#include 
#include 
#include 
#include 
#include 
#include 
#include 
//10
int main(int arg,char** fis){
       int fd;
       int n;
        char buf[5];   
        int ni=0;
 
       fd=open(fis[1],O_RDWR);
      
       if(fd==-1) {printf("Fisierul nu exista");exit(2);}
       do{
         
          if (ni!=0) lseek(fd,ni,SEEK_CUR);
          n=read(fd,buf,5);
          if (ni!=0)lseek(fd,-ni,SEEK_CUR);
          printf("\n buf:=%s",buf); 
          lseek(fd,-5,SEEK_CUR);
          printf("\n scris=%d" , write(fd,&buf,4));
          ni++;
          
          
          
        }
        while(n>=5);
        close(fd);
}

Pr21. Să se scrie un program C, care să scrie în ordine inversă liniile unui fişier fis.in într-un

fişier fis.out, fără a scrie o funcţie recursivă. Se presupune că fişierul fis.in există, iar

fişierul fis.out trebuie creat

#include 
#include 
 
int main(int argc,char **argv)
{
        char **linii;
        int nr_linii=0,i;
        long lungime_fisier;
        FILE *f;
 
        if(argc!=2)
        {
               printf("Sintax: %s \n",argv[0]);
               return 1;
        }
        
        if((f=fopen(argv[1],"r"))==NULL)
        {
                printf("Error opening the file: <%s>\n",argv[1]);
               return 1;
        }
        
        fseek(f,0,SEEK_END);
        lungime_fisier=ftell(f);
        fseek(f,0,SEEK_SET);
        
        linii=(char **)malloc((nr_linii+1)*sizeof(char *));
        
        while(lungime_fisier>ftell(f))
        {
               linii[nr_linii]=(char *)malloc(1000 * sizeof(char));
               fgets(linii[nr_linii],1000,f);
               nr_linii++;
               linii=(char **)realloc(linii,(nr_linii+1)*sizeof(char *));
        }
        
        for(i=nr_linii-1;i>=0;i--)
        {
               printf("%s",linii[i]);
        }
               
        fclose(f);
        
        return 0;
}

Pr 22 Să se scrie un program C care să creeze un fişier binar fis.bin în care să scrie, în

mod aleator, numere şi caractere sub forma: două numere întregi urmate de un

caracter. Caracterul poate fi unul dintre '+', '-', '*' sau '/'. Să se afişeze apoi conţinutul

fişierului. (b) Să se scrie un program C care să citească un anumit grup de numere şi

operatorul ataşat din fişierul fis.bin, să efectueze operaţia dintre cele două numere şi

apoi să se scrie într-un fişier text res.txt o linie de forma:

nr1 operator nr2 = rezultat

Linia de rezultat se va adăuga la sfârşitul fişierului. Numărul grupului vizat din

fişierul binar se specifică în linia de comandă ca parametru. Pentru translatarea unui

întreg în şir de caractere se poate folosi funcţia sprintf

#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
#define BUFSIZE 512
 
typedef struct operatie
{
        float f1, f2;
        char op;
}Op;
 
int main(int argc, char** argv)
{
        int fd, c;
        float f1, f2;
        Op s;
        char buf[BUFSIZE] = "";
        
        if ((fd =open("fis.bin", O_CREAT, 0666)) == -1)
        {
               perror("Eroare la creare fisierului fis.bin\n");
               exit(1);
        }
        
        close(fd);
        
        if ((fd = open("fis.bin", O_WRONLY)) == -1)
        {
               perror("Eroare la deschiderea fisierului fis.bin\n");
               exit(2);
        }
 
        do
        {
               printf("\nOperaor 1 = ");
               scanf("%f", &s.f1);
               printf("\nOperaor 2 = ");
               scanf("%f", &s.f2);
               do
               {
                       printf("\nOperand = ");
                       scanf("%s", &s.op);
               }
               while ((s.op != '+') && (s.op != '-') && (s.op != '*') && (s.op !=
 '/'));
               
               sprintf(buf, "%s%f %f %c\n", &buf, s.f1, s.f2, s.op);
               printf("%s", &buf);
               
               printf("Adaugati: 1 = da / 2 = nu? ");
               scanf("%d", &c);
        }
        while (c != 2);
        
        if (write(fd, &buf, sizeof(buf)) == -1)
        {
                       perror("Eroare la scriere!\n");
                       exit(3);
        }
        
        close(fd);
}

23. (a) Să se scrie un program C care să creeze un fişier binar fis.bin, care să conţină un

număr aleator (maximum 1000), de numere întregi (generate aleator) cuprinse între 0

– 100. Să se afişeze conţinutul fişierului. (b) Să se facă apoi media aritmetică a

fiecărui grup de numere ce sunt cuprinse între două numere cu valoarea zero din

fişier. Să se scrie fiecare grup de numere şi media lor pe câte o linie distinctă din

fişierul text medii.txt. Începutul şi sfârşitul fişierului joacă rolul unui număr cu

valoarea zero, cu excepţia cazului în care primul număr din fişier este zero, respectiv

ultimul este zero. Pentru translatarea unui întreg în şir de caractere se poate folosi

funcţia sprintf.

#include 
#include 
#include 
#include 
#include 
 
int N;
int fisBin, n, nrsRead[1000]; 
void media(int N);
void generateNrs(int N);
FILE *fout;
 
int main()
{
        if ((fisBin=creat("fis.bin", 0666)) <>
        perror("Error creating destination file");
               exit(2);
        } 
        
        
        
        N = rand()%1000;
        generateNrs(N);
        media(N);
        
}
 
void media(int N)
{
        if ((fisBin=open("fis.bin", O_RDWR)) <>
        perror("Error opening source file");
               exit(1);
        }
 
        printf("Media %d");
        int i,n=0,nr = 0;
        for (i=0; i
        {
               if ((n = read(fisBin, &nr, sizeof(int))) <>
               {
                       perror("Error reading file"); 
                               exit(4);
               }
               else 
               {
                       nrsRead[i] = nr;
               }
        }
        close(fisBin);
        
 
        // calcul
        
          
      if ((fout = fopen("fout.txt","w"))<0)>
          {
        perror("Error opening source file");
        exit(1);
      }
        
        
        int sumap = 0, nr_citite = 0, med = 0;
        for (i=0; i
        {
               if ((nrsRead[i] == 0) || (i==N-1)) 
               {
                       med = sumap/nr_citite;
                       sumap = 0;
                       nr_citite = 0;
                       if ((n=fprintf(fout, "Media %d \n", med)) <>
                       {
                               perror("Error writing destination file"); 
                                      exit(4);
                       }
                               
               }
               else
               {
                       if ((n=fprintf(fout, " %d ", nrsRead[i])) <>
                       {
                               perror("Error writing destination file"); 
                                      exit(4);
                       }
                       sumap += nrsRead[i];
                       nr_citite++;
               }
        }
}
 
void generateNrs(int N)
{
 
        if ((fisBin=open("fis.bin", O_RDWR)) <>
        perror("Error opening source file");
               exit(1);
        }
        
        int i =0,nr;
        for (i=0; i
        {
               nr = rand()%100;
               if ((n=write(fisBin, &nr, sizeof(int))) <>
               {
                       perror("Error writing destination file"); 
                               exit(4);
               }
               else printf(" %d ",nr);
        }
        printf("N = %d\n", N);
        close(fisBin);
}

Pr 24  Sa se scrie un program C care citeste caracterele de la
 deplasamentele 0, 20, 40 ,... (pâna la sfârsitul fisierului) dintr-un fisier creat
 anterior si le adauga la sfârsitul fisierului. Se va afisa lungimea
 initiala si cea finala a fisierului. (nota 8) ATENTIE LA DEPLASAMENT.
*/
#include 
#include 
#include 
#include 
 
int main ()
{
int f;
 
f=open("test",O_RDWR);
int flag_read=0;
int lungime_fisier=lseek(f,0,SEEK_END);
char b;
if (f>0)
{
    do 
    {
        lseek(f,flag_read,SEEK_SET);
        read(f,&b,1);
        printf("\n citim %c",b);
        lseek(f,0,SEEK_END);
        write(f,&b,1);
        flag_read+=20; 
    }while (flag_read+4
    printf("\nlungimea fiserului inaite %d si dupa
 %d",lungime_fisier,lseek(f,0,SEEK_END));
    close(f);
}
 
 
 
return 0;
}

27. Să se scrie un program care să permită inserarea unor şiruri de caractere citite de la

intrarea standard într-un fişier, începând cu o anumită poziţie. Programul afişează

dimensiunea iniţială şi finală a fişierului. Apelul programului se face sub forma:

rw poz fis

#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
 
 
 
main( int argc, char *argv[])
{
 
char buf[100],buf2[100];
char c;
int fd;
int i,j;
int poz,nr,new_poz;
 
poz = atoi(argv[1]);
 
j=0;
 
if (argc != 3)
        {
        printf("nu-s bine argumentele\n");
        exit(0);
        }
 
 
if ((fd=open(argv[2],O_RDWR)) == -1)
        printf("Eroare la deschidere fisier");
 
 
scanf("%c",&c);
i=0;
 
while(c != '.')
        {
        buf[i]=c;
        scanf("%c",&c);
        i++;
        }
 
 
 
lseek(fd,poz,SEEK_SET);
 
if ((nr = read(fd,&buf2,sizeof(buf2))) == -1)
        printf("eroare la citire");
 
lseek(fd,poz,SEEK_SET);
 
if (write(fd,&buf,i) == -1)
        printf("Eroare la scriere");
 
new_poz=poz+i;
 
lseek(fd,new_poz,SEEK_SET);
 
if (write(fd,&buf2,nr) == -1)
        printf("Eroare la scriere");
 
 
}
 

33. Să se scrie un program C care să permită ştergerea tuturor copiilor unui fişier din

întreaga structură a unui director. Pentru identificarea fişierului se va folosi numele,

tipul (fişier normal) şi lungimea sa. Numele fişierului şi al directorului se transmit în

linia de comandă.
 
#include
#include
 
void functie(char*dir)
{
        struct dirent* entit;
        DIR* director;
        director=opendir(dir);
        char temp[100];
        if (director!=0)
        {
               while ((entit=readdir(director))!=0)
               {
                       strcpy(temp,"");
                       strcat(temp,dir);
                       strcat(temp,"/");
                       strcat(temp,entit->d_name);
                       if ((strcmp(entit->d_name,".")!=0)&&(strcmp(entit->d_name,"..")!=0))
                               functie(temp);
                       
               }
               closedir(director);
               printf("Sterg folder %s\n",dir);
               execlp("rd","rd",dir,0);//comanda de  sters
        }
        else
        {
               printf("Sterg Fisier: %s\n",dir);
               unlink(dir);
        }              
}
 
int main(int argc, char*argv[])
{
        functie(argv[1]);
        return 0;
}
 

Pr.34 Să se scrie un program care să permită traversarea unei arbore de fişiere afişând

pentru toate fişierele găsite tipul, dimensiunea şi drepturile de acces. Programul

primeşte ca argument în linia de comanda numele directorului de start

#include

#include

#include

#include

#include

void listDir(char *dirName)

{

DIR* dir;

struct dirent *dirEntry;

struct stat inode;

char name[1000];

char tmp[1000]="";

dir = opendir(dirName);

if (dir == 0) {perror ("Eroare deschidere director");exit(1);}

while ((dirEntry=readdir(dir)) != 0) {

sprintf(name,"%s/%s",dirName,dirEntry->d_name);

lstat (name, &inode);

// test the type of file

if (S_ISREG(inode.st_mode)) printf ("fis ");

else if (S_ISLNK(inode.st_mode)) printf ("lnk ");

else if (S_ISDIR(inode.st_mode)) printf("dir ");

else;

printf(" %s\n", dirEntry->d_name);

}

rewinddir(dir);

while ((dirEntry=readdir(dir)) != 0) {

sprintf(name,"%s/%s",dirName,dirEntry->d_name);

lstat (name, &inode);

if (S_ISDIR(inode.st_mode))

{

if ((strcmp(dirEntry->d_name,"..")!=0) && (strcmp(dirEntry->d_name,".")!=0))

{strcpy(tmp,dirName);

strcat(tmp,"/");

strcat(tmp,dirEntry->d_name);

printf("\n Dir %s contine:\n",tmp);

listDir(tmp);

}

}

}

}

int main(int argc, char **argv)

{

if (argc != 2) {

printf ("UTILIZARE: %s nume_dir\n", argv[0]);

exit(0);

}

printf("Directoru %s contine:\n",argv[1]);

listDir(argv[1]);

}

Pr.35 Să se scrie programul C care să permită ştergerea unui director cu întregul lui

conţinut. Numele directorului este transmis în linia de comandă

#include

#include

#include

#include

#include

#include

void cleanDir(char *dirName)

{

DIR* dir;

struct dirent *dirEntry;

struct stat inode;

char name[1000];

char tmp[100];

dir = opendir(dirName);

if (dir == 0) {perror ("Eroare deschidere director");exit(1);}

while ((dirEntry=readdir(dir)) != 0) {

sprintf(name,"%s/%s",dirName,dirEntry->d_name);

lstat (name, &inode);

// test the type of file

if (S_ISREG(inode.st_mode))

{strcpy(tmp,"rm ");

strcat(tmp,dirName);

strcat(tmp,"/");

strcat(tmp,dirEntry->d_name);

// printf("%s\n",tmp);

system(tmp);

}

}

strcpy(tmp,"rmdir ");

strcat(tmp,dirName);

system(tmp);

}

int main(int argc, char** argv)

{

cleanDir(argv[1]);

}

36. Să se scrie un program C care caută un fişier în întreaga structură a unui arbore de

fişiere şi directoare, pornind de la un director dat. Numele fişierului şi al directorului

de pornire se transmit ca parametrii în linia de comandă

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
void deldir (char *dir, char *file);
char *path;
 
int main (int argc,char **argv){
        //printf("%s %s\n",argv[1],argv[2]);
        deldir(argv[1],argv[2]);
        printf("Fisierul a fost gasit in:%s:",path);
}
 
void deldir (char *dir, char *file){
        
DIR *dp;
FILE *fis;
struct dirent *entry;
struct stat statbuf;
char crtdir;
char name[255];
 
dp = opendir(dir);
chdir(dir);
while ((entry = readdir(dp)) != 0){
        sprintf(name,"%s%s",dir, entry->d_name);
        lstat(name,&statbuf);
        if (S_ISDIR(statbuf.st_mode)){
               if (strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) ==
 0) continue;
               deldir(entry->d_name,file);
               }
        else 
               if (strcmp(file,entry->d_name) == 0 ){ 
                       printf("Am gasit fisierul");
                       //syscall(&pwd);
                       //crtdir = 'pwd;
                       //printf("Calea %s", $crtdir);
                       path = name;
                       continue;
               }
               printf("%s \n\n ",entry->d_name);
}
 
//printf("asdasdasd asdas da %s \n",entry->d_name);
closedir(dp);
chdir("..");
}

Pr.39Interpretor de comenzi cu parametri - 1. Să se implementeze în C, folosind funcţiile

fork şi execvp, un interpretor de comenzi care să accepte comenzi cu parametri

#include

#include

void parse(char *line, char **argv)

{

while (*line != '\0') { /* if not the end of line ....... */

while (*line == ' ' || *line == '\t' || *line == '\n')

*line++ = '\0'; /* replace white spaces with 0 */

*argv++ = line; /* save the argument position */

while (*line != '\0' && *line != ' ' &&

*line != '\t' && *line != '\n')

line++; /* skip the argument until ... */

}

*argv = '\0'; /* mark the end of argument list */

}

void execute(char **argv)

{

pid_t pid;

int status;

if ((pid = fork()) < style=""> /* fork a child process */

printf("*** ERROR: forking child process failed\n");

exit(1);

}

else if (pid == 0) { /* for the child process: */

if (execvp(*argv, argv) < style=""> /* execute the command */

printf("*** ERROR: exec failed\n");

exit(1);

}

}

else { /* for the parent: */

while (wait(&status) != pid) /* wait for completion */

;

}

}

void main(void)

{

char line[1024]; /* the input line */

char *argv[64]; /* the command line argument */

while (1) { /* repeat until done .... */

printf("Shell -> "); /* display a prompt */

gets(line); /* read in the command line */

printf("\n");

parse(line, argv); /* parse the line */

if (strcmp(argv[0], "exit") == 0) /* is it an "exit"? */

exit(0); /* exit if it is */

execute(argv); /* otherwise, execute the command */

}

}

Pr.42 Linia de comandă – pipe3. Folosind fişiere pipe fără nume să se scrie un interpretor

de comenzi care acceptă în linia de comandă construcţii de forma de mai jos. Pentru

preluarea numelor comenziilor din linia de comandă se poate folosi funcţia strsep.

#include

#include

int parse(char* line, char** argv)

{ char* pch;

int cnt=0;

pch = strtok (line," |");

argv[cnt]=pch;

while (pch != NULL)

{

pch = strtok (NULL, " |");

cnt++;

argv[cnt]=pch;

}

return cnt;

}

void execute(char* cmd1, char* cmd2, char* cmd3)

{

pid_t pid1,pid2,pid3;

int status,n,buf[100],fdPipe[2],fdPipe2[2];;

pipe(fdPipe);

pipe(fdPipe2);

pid1 = fork(); // creare fiu 1

if (pid1 < style=""> exit(1); }

if (pid1 == 0) { // fiu 1

close(fdPipe[0]);

dup2(fdPipe[1], 1); // redirectare STDOUT

close(fdPipe[1]); // in pipe

close(fdPipe2[0]);

close(fdPipe2[1]);

execlp(cmd1, cmd1, NULL);

perror("Eroare executie comanda 1");

exit(0);

}

pid2 = fork(); // creare fiu 2

if (pid2 <>

if (pid2 == 0) { // fiu 2

close(fdPipe[1]);

dup2(fdPipe[0], 0); // redirectare STDIN

close(fdPipe[0]); // din pipe

close(fdPipe2[0]);

dup2(fdPipe2[1], 1); // redirectare STDOUT

close(fdPipe2[1]); // in pipe2 !!!

execlp(cmd2, cmd2, NULL);

perror("Eroare executie comanda 2");

exit(0);

}

pid3 = fork(); // creare fiu 3

if (pid3 <>

if (pid3 == 0) { // fiu 3

close(fdPipe2[1]);

dup2(fdPipe2[0], 0); // redirectare STDIN

close(fdPipe2[0]); // din pipe2 !!!

close(fdPipe[0]);

close(fdPipe[1]);

execlp(cmd3, cmd3, NULL);

perror("Eroare executie comanda 3");

exit(0);

}

close(fdPipe[0]);

close(fdPipe[1]);

close(fdPipe2[0]);

close(fdPipe2[1]);

waitpid(pid1, NULL, 0); // asteapta primul fiu

waitpid(pid2, NULL, 0); // asteapta al doilea fiu

waitpid(pid3, NULL, 0); // asteapta al treilea fiu

}

void main(void)

{ int n;

char line[1024];

char *argv[64];

while (1) {

printf("C:\> ");

gets(line);

printf("\n");

n=parse(line, argv);

if (strcmp(argv[0], "exit") == 0)

exit(0);

execute(argv[0],argv[1],argv[2]);

}

}

Pr 45.  Sa se scrie un program C, care scrie la sfârsitul unui fisier binar
 pid.bin PID-ul procesului curent. Sa se scrie apoi un alt program C,
 care sa creeze N procese concurente, care sa execute fiecare
 executabilul obtinut din primul program C. Nici unul dintre cele N procese nu
 poate sa-si continue executia pâna ce toate N procesele nu si-au scris
 PID-ul propriu în fisier. În final, fiecare proces afiseaza PID-ul
 procesului urmator. N se presupune cunoscut la scrierea programului.
*/
#include 
#include 
#include 
#include 
#include 
#include 
 
int main(int argc,char** argv)
{
    int N;
    int fd,pid;
    int dimi,dima;
    printf("test\n");
    sscanf(argv[0],"%d",&N);
    printf("N=%d\n",N);
    sscanf(argv[1],"%d",&fd) ;
    printf("fd=%d",fd);
    //open(fd,O_RDWR);
    pid=getpid();
    write(fd,&pid,sizeof(int));
    printf("procesul cu pidul %d si-a scris propriul pid in
 fisier\n",pid);
    sscanf(argv[2],"%d",&dimi);
    printf("dimi=%d\n",dimi);
    dima=lseek(fd,0,SEEK_END);
    printf("dima=%d\n",dima);
    while(((dima-dimi)/sizeof(int))
    {
        //printf("sunt inainte de sleep\n");
        sleep(1);
        dima=lseek(fd,0,SEEK_END);
    }   
    //if(((dima-dimi)/sizeof(int))>=N)
    //{
        lseek(fd,dimi,SEEK_SET);
        int i=0;
        int pidNext;
        int val;
        while(i
        {
            read(fd,&val,sizeof(int));
            if(val==pid)
            {
               read(fd,&pidNext,sizeof(int));     
               lseek(fd,dima,SEEK_SET);
               write(fd,&pidNext,sizeof(int));
               printf("procesul cu pidul %d a scris in fisier pidul procesului
 urm=%d\n",pid,pidNext);
               exit(1);
            }
            i++;
        }
    //} 
}       

Pr47A Procese orfane şi zombie. a) Să se scrie un program C care să pună în evidenţă

faptul că procesele fiu ale unui proces care se termină devin fii procesului init

#include

#include

main()

{

int pid;

if((pid=fork())==0)

{

int ppid;

ppid=getppid();

printf("\nFiu: Cod parinte:%d\n",ppid);

sleep(3);

ppid=getppid();

printf("\nFiu: Cod parinte dupa 3 secunde:%d\n",ppid);

if (ppid==1) printf("\nFiu' e orfan saracu\n");

exit(0);

}

else

{

printf("Parintele se duce la o tzigara...\n");

exit(0);

}

}

Pr.47B b) Să

se scrie apoi un alt program C, care să pună în evidenţă un proces în starea zombie.

#include

#include

main()

{

int pid;

if((pid=fork())==0)

{

printf("\nBuuuuu, I'm a zombie and my PID is %d...\nMy parent's PID is %d\n", getpid(), getppid());

exit(0);

}

else

{

sleep(3);

// wait(&pid);

system("ps","-l");

exit(0);

}

}

Pr.48Funcţionalitate system fără parametri. Să se scrie un program C care să

implementeze funcţionalitatea funcţiei system. Se vor folosi funcţiile fork şi execlp.

Se presupune că comenzile acceptate de către program nu au parametri.

#include

#include

int main(int argc,char** argv)

{

int pid;

if((pid=fork())==0)

{int v;

if((v=execlp(argv[1],0))<0) style="">

exit(0);

}

else

{

wait(&pid);

exit(0);

}

}

Pr.50 Excludere mutuală - Fişier. Să se scrie codul C a două procese diferite, care citesc

un număr scris într-un fişier text, îl incrementează şi apoi îl scriu înapoi. Această

operaţie este efectuată de mai multe ori de către fiecare proces (de N1 ori de către

primul proces şi de N2 ori de către al doilea proces). Valoarea iniţială a numărului

este 0. Să se asigure, folosind semafoare, faptul că valoarea finală a numărului este

N1 + N2

#include

#include

#include

#include

#include

#define N 1

void P(int semId, int semNr){

struct sembuf op ={semNr, -1, 0};

semop(semId, &op, 1);

}

void V(int semId, int semNr){

struct sembuf op = {semNr, +1, 0};

semop(semId, &op, 1);

}

int main (int argc, char **argv){

int i, pid,fd,n;

char buf[10];

int semId = semget(IPC_PRIVATE, 2, IPC_CREAT | 0600);

if (semId <0>

semctl(semId, 0, SETVAL, 1);

semctl(semId, 1, SETVAL, 0);

fd=open("/home/eminence/tst.txt",O_WRONLY | O_CREAT | O_TRUNC,0777);

write(fd,"0",1);close(fd);

pid =fork();

if (pid ==0)

do

{char*x;

P(semId, 0);

fd=open("/home/eminence/tst.txt",O_RDONLY);

n=read(fd,buf,10);buf[n]=0;

n=atoi(buf);

close(fd);

printf("Procesul 1 read: v=%s\n",buf);

n++;

sprintf(buf,"%d",n);

fd=open("/home/eminence/tst.txt",O_WRONLY | O_TRUNC);

write(fd,buf,strlen(buf));

printf("Procesul 1 write: v=%d\n",n);

close(fd);

//gets(x);

V(semId, 1);

} while (n<10);

else

do {char* x;

P(semId, 1);

fd=open("/home/eminence/tst.txt",O_RDONLY);

n=read(fd,buf,10);buf[n]=0;

n=atoi(buf);

close(fd);

printf("Procesul 2 read: v=%s\n",buf);

n++;

sprintf(buf,"%d",n);

fd=open("/home/eminence/tst.txt",O_WRONLY | O_TRUNC);

write(fd,buf,strlen(buf));

printf("Procesul 2 write: v=%d\n",n);

close(fd);

// gets(x);

V(semId,0);

} while (n<10);}

Pr.51 Excludere mutuală - Semafoare. Să se scrie un program C care creează N thread-uri,

fiecare incrementând de M ori o variabilă globală a procesului, variabilă care are

iniţial valoarea 0. Folosind semafoare, să se asigure faptul că valoarea finală a

variabilei este N*M. (

//compilare - gcc 51.c -lpthread -o 51.exe

#include

#include

#include

int var=0,n=7,m=8;

void P(int semId, int semNr){

struct sembuf op ={semNr, -1, 0};

semop(semId, &op, 1);

}

void V(int semId, int semNr){

struct sembuf op = {semNr, +1, 0};

semop(semId, &op, 1);

}

void* func_th(void* arg)

{int i;

sleep(1);

for(i=0;i

}

main()

{int i,arg1=1; //nr de thread-uri

pthread_t th[20];

int semId = semget(10, 2, IPC_CREAT | 0600);

if (semId <0>

semctl(semId, 0, SETVAL, 0);

semctl(semId, 1, SETVAL, 1);

for(i=0;i

{

pthread_create(&th[i],NULL,&func_th,&arg1);

pthread_join(th[i],NULL);

}

printf("var=%d\n",var);

}

Pr.53Afişare alternativă 2 - Sem. Să se scrie codul C al două procese neaflate în relaţia

părinte-fiu, care execută într-o buclă N paşi. La fiecare pas, fiecare proces îşi afişează

identificatorul şi, alături, valoarea curentă a unei variabile locale, pe care o

icrementează apoi cu 1. Să se sincronizeze prin semafoare cele două procese, astfel

încât afişarea să se facă alternativ, odată un proces, apoi celălalt ş.a.m.d.

#include

#include

#include

#include

#include

#define N 1

void P(int semId, int semNr){

struct sembuf op ={semNr, -1, 0};

semop(semId, &op, 1);

}

void V(int semId, int semNr){

struct sembuf op = {semNr, +1, 0};

semop(semId, &op, 1);

}

int main (int argc, char **argv){

int i, pid,fd,n;

char buf[10];

int semId = semget(10, 2, IPC_CREAT | 0600);

if (semId <0>

semctl(semId, 0, SETVAL, 0);

semctl(semId, 1, SETVAL, 1);

pid =getpid();

while(1){

P(semId, 0);

printf("Procesul %d se baga in seama cu semaforu ID=%d\n",pid,semId);

V(semId, 1);

}

}

53_2

#include

#include

#include

#include

#include

#define N 1

void P(int semId, int semNr){

struct sembuf op ={semNr, -1, 0};

semop(semId, &op, 1);

}

void V(int semId, int semNr){

struct sembuf op = {semNr, +1, 0};

semop(semId, &op, 1);

}

int main (int argc, char **argv){

int i, pid,fd,n;

char buf[10];

int semId = semget(10, 1,IPC_EXCL);

printf("ID=%d\n",semId);

if (semId <0>

/*semctl(semId, 0, SETVAL, 1);

semctl(semId, 1, SETVAL, 0); */

pid =getpid();

while(1){

P(semId, 1);

printf("Procesul %d se baga in seama cu semafor=%d\n",pid,semId);

V(semId, 0);

}

}

Pr.62 Afişare alternativă N -Pipe. Să se scrie un program C, care să creeze N threaduri,

care execută într-o buclă M paşi. La fiecare pas, fiecare thread îşi afişează

identificatorul şi alături valoarea curentă a unei variabile globale, pe care o

icrementează apoi cu 1. Să se sincronizeze prin fişiere pipe cele două N threaduri,

astfel încât afişarea să se facă într-o ordine prestabilită: threadul 1, threadul 2, ...,

threadul N, threadul1, threadul 2, etc

#include

#include

#include

#include

int fdSpreStanga[2],fdSpreDreapta[2];

int pid, n;

int buf[100];

main(int argc, char** argv)

{int dim;

int v=0;

pipe(fdSpreStanga);

pipe(fdSpreDreapta);

pid = fork();

if (pid == 0) { // proces fiu

int tmp;

char str[100];

close(fdSpreStanga[0]);

close(fdSpreDreapta[1]);

do

{

n=read(fdSpreDreapta[0], buf, 10);

buf[n] = 0;

printf("Fiul a receptionat: %s\n", buf);

tmp=atoi(buf);

tmp*=tmp;

sprintf(str,"%d",tmp);

write(fdSpreStanga[1], str, 10);

printf("Fiul a transmis: %d\n",tmp);

}

while (v<10);

}

else { // proces parinte

char str[100];

close(fdSpreStanga[1]);

close(fdSpreDreapta[0]);

while (v<=10)

{

v++;

sprintf(str,"%d",v);

write(fdSpreDreapta[1], str,10);

printf("Parintele a transmis: %s\n",str);

n=read(fdSpreStanga[0], buf, 10);

buf[n] = 0;

printf("Parintele a receptionat: %s\n", buf);

}

close(fdSpreStanga[0]);

close(fdSpreDreapta[1]);

}

}

64. Pipe bidirecţional cu nume - 1. Să se scrie codul C al două procese. Cele două

procese comunică prin fişiere pipe cu nume. Primul proces transmite celui de-al

doilea, în format binar, numerele naturale de la 1 la N. Acesta le preia, le calculează

pătratul şi transmite înapoi rezultatul primului proces, care îl afişează pe ecra

#include

#include

#include

#include

#include

// codul C al primului proces

main()

{

pid_t pid;int n,v=0;

char buf[100];

char str[100];

int fd,fd2;

mkfifo("/tmp/FIFO", 0600);

mkfifo("/tmp/FIFO2", 0600);

while(v<10)>

v++;

sprintf(str,"%d",v);

if(v==1){pid=fork();

if (pid==0) execlp("./tst2",NULL); //lanseaza fiu in exec (de fapt nu-i fiu, ii alt proces)

}

fd = open("/tmp/FIFO", O_WRONLY);

if (fd <>

write(fd, str, strlen(str)); //fd,str,lung

printf("Parintele a transmis: %s\n", str);

fd2 = open("/tmp/FIFO2", O_RDONLY);

n = read(fd2, buf, 21);

buf[n] = 0;

printf("Parintele a receptionat: %s\n", buf);

close(fd2);

}

//exit(0);

}

64_2

#include

#include

#include

#include

#include

// codul C al doilea proces

main()

{

int n,v=0;

int tmp;char str[100];

int fd,fd2;

char buf[100];

do {

fd = open("/tmp/FIFO", O_RDONLY);

if (fd <>

n = read(fd, buf, 21);

close(fd);

buf[n] = 0;

printf("Fiul a primit: %s\n", buf);

v=atoi(buf);

tmp=v*v;

sprintf(str,"%d",tmp);

fd2 = open("/tmp/FIFO2", O_WRONLY);

printf("Fiul a transmis: %s\n", str);

write(fd2, str, strlen(str)); //fd,str,lung

} while(v<10);

printf("Fiu has left the building\n");

exit(0);

}