[so] Tema4 (relativ urgent)

adrian nistor adriannistorrr at yahoo.com
Mon Jan 2 15:13:02 EET 2006


      Buna.
   
  Am o intrebare (mai degraba problema) la tema 4 . aio_suspend nu este intrerupt de semnale. 
  As apreacia mult un raspuns.
   
  Am facut un program de test, care in threarul principal astepta sa citeasca de la tastatura (printr-un select pe file descriptorul zero 0). Tot in threadul principal(inainte de select, e lansat un aio_read). Apoi creez un thread in care dau un sleep de 1000 de secunde dupa care dau aio_suspend-ul. Cand se citeste de la tastatura ceva, e trimis un semnal catre acel thread prin pthread_kill. Deci eu practic pot trimite semnale de cate ori vreau. Semnalul trimis intreruop usleep (deci nu sleep, ci usleep), dupa care threadul copil logic ajunge la aio_select. Pe acesta insa nu mai reuseste sa il trezeasca. In functia de tratare a semnalului SIGRTMAX e pus un printf("ssssss"), astfel ca se vade ca semanalul ajunge. Deci acelasi semnal care intrerupe usleep-ul nu mai reuseste sa intrerupa aio_selectul.
   
  Din codul atastat am mai scos unele secvente care afisatu tid-ul, etc etc, pentru a fi mai lizibil. Dar daca mai adaug si tid-ul curent prin printf-uri, e clar ca threadul primeste semnalul; de altfel, facptul ca usleepul e intrerupt face acest lucru si mai clar. In codul meu initial, aveam defapt 3-4 de usleepuri, pe care le trezeam pe toate cu semanale, fara nici o problema. Le-am scos din codul tirmis tot pentru a fi mai lizibil coul. Dar daca vrei poti adauga acel usleep de mai multe ori unu dupa altul, si prin semnal le vei putea intrerupe pe toate. aio_suspend nu merge in sa intrerupt.
   
  Codul afiseaza
  TASTATURA
  TASTATURA ^^^^^ssssssssssssssssssssssssssssssssssssss    
                              cand este trimis un semanl
   
   
  apoi 
  66666666 inainte de usleep
  777777777 imediat dupa usleep si ininte de a intra in  aio_suspend
  7777777777^^^^^^ %d imadiat dupa aio_suspend
                        %d contine codul de eroare a lui aio_suspend, care desi ar treuyi sa fie -1 (daca ar fi intrerupt) e tot timpul 0(ca si cum nu e intrerupt; in fond corect , deoarece semnalelele nu reusesc sa il intrerupa(ceea ce nu mai e corect)).
   
   
  Programul se compileaza cu 
      g++ -Wall -g TestD.cpp -o testD -pthread -lrt
   
   
  si un exemplu de rulare ar fi:
  
  ./testD /home/adrian/adrian.zip 0 90000000
   
  Ca sa astepte  mai mult  la aio_suspend, fisierul  din care se citeste (in caul de fata  /home/adrian/adrian.zip) trebuie sa fie  mare (eu am facut o arhiva de 92MB)
  dica care sa se si citesca mult 90000000==90.000.000 adica 90MB. Daca e rulat pe fisiere mici sau daca parametru argv[3] e mic de genu 90 (adica se citesc 90 byti)  citirea asiun crona se va fi terminat intinte de a ajunge la aio_suspend. Deci tebuie rulat pe fisiere mari si cu parametru mare (92 MB respectiv 90000000).
   
   
   
  In concluzie, se porneste programulm, si cand afiseaza 66666666 insemana ca a ajuns la usleep. aici, trebuie tastat ceva si ENTEE, , se iese datorita intreruperii SIGRTMAX (se afiseaza ssssssssssssssssssssssss, adica intreruperea a fost tratata), apoi va fi afisat 77777777 adica sa ajuns la aio_suspend. Daca fiserul e mare si argv[3 ] e mare, programul se blocheaza. Daca tastez, se va afisa ssssssssssssssssssssss adica intresuperile snt vazute si tratate, doar ca nu se afiseaza si 7777777777^^^^^^^^-1 adica nu se iese din aio_suspend datorita intreruperilor. Doar dupa ceva timp se va iesi si din aio_suspend adica se afiseaza 7777777777^^^^^^^^0  adica s-a iesit din aio_suspend datorita terminarii citirii asincrone.
   
   
   
  Nu imi dau seman care e problema (deoarece programul; pare destul de simplu  si de clar). Nu imi dau semana de ce usleep este intrerupt iar aio_suspend nu. In alte versiuni, am mai incercat in loc de usleep si cu functii de genul  "sigwait"
  , care im i arata ca semanlul ajunge la thread, dar apoi cand ajung si la aio_suspend, acesta nu e trezit de intrerupere, desi aceasta e treatata.
   
   
   
   
   
  Multumesc anticipat 
   
  Adrian Nistor
   
   
  CODUL ESTE:
     #include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <signal.h>
#include <aio.h>

typedef struct 
{
int tid;
}ParametriThread;

extern int errno;
aiocb cb;
pthread_t Fir;
pthread_t FirP;
timespec t;

//./testD /home/adrian/adrian.zip 0 90000000
//g++ -Wall -g TestD.cpp -o testD -pthread -lrt
//===========================

void FunctiaSIGRTMAX(int signum,siginfo_t *info,void *param)
{
printf("ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\n");fflush(stdout);

}
//--------------------------------
void InitilizeazaSigactionSIGRTMAX()
{
struct sigaction semnale;
memset(&semnale,0,sizeof(semnale));
sigset_t masca;
sigemptyset(&masca);//ca nu vreau sa blochez nici un semnal
semnale.sa_flags=SA_SIGINFO;
semnale.sa_mask=masca;
semnale.sa_sigaction=FunctiaSIGRTMAX;
int xxx=sigaction(SIGRTMIN ,&semnale,(struct sigaction*)NULL); 
if(xxx==-1)
{
perror("ERR testD.cpp InitilizeazaSigactionSIGRTMAX;la sigaction;NAT\n");
exit(1);
}
}
//-------------------------------------------------------------------------------------------------------------------------------

//=======================
void TrateazaInputTastatura()
{
printf("TASTATURA\n");
int xxx=pthread_kill(Fir,SIGRTMIN); 
if(xxx==-1)
{
perror("ERR testD.cpp TrateazaInputTastatura; la pthread_kill");
}
char *c;
c=(char*)malloc(1999);
read(STDIN_FILENO,c,1999);
printf("TASTATURA^^^ ");
}
//------------------------------------------------------
void* FunctieThread(void *params)
{
aiocb *cblist[2];
cblist[0]=&cb;
cblist[1]=NULL;
int nr=2; 
t.tv_nsec=2000;
t.tv_sec=2000;

int ddd=1999;

printf("666666666\n");
usleep(1000000000);
printf("77777777\n");

int xxx=1999;
xxx=aio_suspend(cblist,nr,&t);
printf("77777777^^^ %d\n",xxx);fflush(stdout);

exit(1);
}

int main(int argc,char*argv[])
{
InitilizeazaSigactionSIGRTMAX();


//variabile pentru conexiune
int soketClientNou;
int clilen;
sockaddr_in cli_addr;
fd_set readFdSet; //fd_set folosit in select()
fd_set tmpFdSet; //fd_set folosit temporar
int fdMax;

//lansare citire
//citirea asincrona
int fis1=open(argv[1],O_RDWR);
if(fis1==-1)
{
perror("ERR1");
exit(1);
}

char *undePun1;
undePun1=(char*)malloc(100000000);
memset(undePun1,0,100000000);
memset(&cb,0,sizeof(aiocb));
cb.aio_fildes=fis1;
cb.aio_lio_opcode=LIO_READ;
cb.aio_reqprio=0;
cb.aio_buf=undePun1;
cb.aio_offset=atoi(argv[2]);
cb.aio_nbytes=atoi(argv[3]);
cb.aio_sigevent.sigev_notify=SIGEV_NONE;

int xxx1;
xxx1=aio_read(&cb);
if(xxx1==-1)
{
perror("ERR2");
}

//end lansare citire

//end variabile pentru conexiune

FD_SET(0,&readFdSet);
fdMax = 0;



//lansez thread
ParametriThread firArgs;
firArgs.tid=1999;//defapt poate chiar osa imi trebuiasca vreodta la ceva
int xxx=pthread_create(&Fir, NULL, &FunctieThread, &firArgs);
if(xxx==-1)
{
perror("ERR server.cpp CreazaPoolThreaduri;la crearea threadA;NAT\n");
exit(1);
}

FirP=pthread_self();
//end lansare tread


//asteapta comenzi de la tastatura
while(1==1)
{

tmpFdSet =readFdSet; 

//selectul , e facut in while pentru a nu fi intrerupt de vrun semnal;daca e intrerupt , reporneste
// nu e cazul aici dar just in case 
while (1==1)
{

int nrDescriptoriSchimbati=select(fdMax + 1, &tmpFdSet, NULL, NULL,NULL);//timeout==infinit

if (nrDescriptoriSchimbati == -1 && errno==EINTR )
{ 
continue;
}
if(nrDescriptoriSchimbati == -1 && errno!=EINTR )
{
perror("ERR server.cpp main; select;NAT");
exit(1);
}
if(nrDescriptoriSchimbati ==0)
{
continue;//a expirat timpul de asteptate
}
if(nrDescriptoriSchimbati>0)
{
break;//chiar am primit ceva 
}
}

int i=0;
for(i = 0; i <= fdMax; i++) 
{ 
if (FD_ISSET(i, &tmpFdSet)) 
{ 
if(i==0)//adica tastatura
{
TrateazaInputTastatura();
//FD_CLR(0,&readFdSet);
} 

}
} 
}

exit(1);



pthread_join(Fir, NULL);
}









		
---------------------------------
Yahoo! Photos
 Ring in the New Year with Photo Calendars. Add photos, events, holidays, whatever.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://cursuri.cs.pub.ro/pipermail/so/attachments/20060102/f01a8840/attachment.html


More information about the so mailing list