[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