Problem z select()

0

Witam!

Mam program, ktory tworzy okreslona ilosc rurek, a nastepnie zapisuje
do losowo wybranej rurki. Nad monitorowaniem stanu deskryptorów czuwa
funkcja select(). Nie wiem jednak dlaczego funkcja select() zwraca 0
tak jakby nic sie nie stalo.

Oto listing...

#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>

#define MAXFDS    1000
#define MAXBYTES  1024*1024

fd_set readset;

int pipeArr[MAXFDS][2];
int useSelect = 1;

void fatal(char *str)
{
  printf("%s\nErrno = %d\n", str, errno);
  exit(-1);
}

void createPipes(int num)
{
  int i;
  FD_ZERO(&readset);

  for (i = 0; i < num; i++)
    {
      int ret = pipe(pipeArr[i]);
      if (ret < 0) fatal("could not create pipe...check fd limit");
       FD_SET(pipeArr[i][0],&readset);
    }
}

int writeRandom(int num)
{
  char buf[100];
  int index = (int) random() % num;
  if (write(pipeArr[index][1],buf,10) != 10) fatal("could not write to
pipe");
  return index;
}

int readData(int num)
{
  int i;
  ssize_t readret;
  char buf[100];
  int totreads=0;

  for (i = 0; i < num; i++)
    {
      if (FD_ISSET(pipeArr[i][0],&readset))
	{
	  if ( (readret = read(pipeArr[i][0], buf, 10)) <= 0 )
fatal("read() failed");
	  totreads += readret;
	  return totreads;
	}
    }
  return totreads;
}

void writeReadLoops(int num)
{
  struct timeval t1,t2;
  struct timeval t3;

  char buf[100];
  int count=0;
  int reads=0;
  int selectret, readret, pollret, idx;

  puts("Starting write / [select] / read loop:");
  gettimeofday(&t1, NULL);
  while ( reads < MAXBYTES )
    {
      idx = writeRandom(num);
      count += 1;
      if (useSelect==1)
	{
	  t3.tv_sec = 0;
	  t3.tv_usec = 0;

	  selectret = select(num+1, &readset, NULL, NULL, &t3);
	  if (selectret <= 0) fatal("select() failed");
	  readret = readData(num);
	  if (readret <= 0) fatal("read() failed");
	}
      else /* no polling - we know the index! */
	{
	  if ( (readret = read(pipeArr[idx][0], buf, 10)) <= 0 )
	    fatal("could not read what was just written");
	}
      reads += readret;
    }
  gettimeofday(&t2, NULL);
  if (useSelect == 1) printf("%d write()/select()/read()s on %d file
descriptor(s)", count,num);
  else printf("%d write()/read()s on %d file descriptor(s)",
count,num);

  printf(" took : %d msec.\n", (t2.tv_sec - t1.tv_sec) * 1000 +
	 ((t2.tv_usec - t1.tv_usec)/1000));
}

main(int argc, char **argv)
{

  int numFds;

  numFds = atoi(argv[1]);

  createPipes(numFds);
  printf("Opened %d file descriptor(s)\n", numFds);
  writeReadLoops(numFds);
}
0

Eee :) Rurki? Potoki.

0

Przeczytałes mana, ale bez zrozumienia :

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

n is the highest-numbered descriptor in any of the three sets, plus 1.

Czyli nie ilośc deskryptorów, tylko maksymalna wartość desktyptora z 3 zbiorów powiększona o 1 :)

Proponuje cos takiego (tak, albo ustaw maxpipedesc jako global i nic w wywyalaniach/naglowkach funkcji nie zmieniaj):

void createPipes(int num,int* maxpipedesc)
{
  *maxpipedesc=0;
  int i;
  FD_ZERO(&readset);

  for (i = 0; i < num; i++)
    {
      int ret = pipe(pipeArr[i]);
      if (ret < 0) fatal("could not create pipe...check fd limit");
      if(maxpipedesc<ret)maxpipedesc=ret;
       FD_SET(pipeArr[i][0],&readset);
    }
}


void writeReadLoops(int num,int maxpipedesc){

  select(maxpipedesc+1, ...)

}

main(int argc, char **argv)
{

  int numFds;

  numFds = atoi(argv[1]);
  int maxpipe;
  createPipes(numFds,&maxpipe);
  printf("Opened %d file descriptor(s)\n", numFds);
  writeReadLoops(numFds,maxpipe);
}
0

Dzieki serdeczne! Faktycznie... zle zrozumialem pierwszy parametr w select().
Zrobilem tak jak napisales, jednak cos jest jeszcze nie tak... select() wciaz zwraca zero :(

0

sorki moj błąd:

int ret = pipe(pipeArr[i]);
if (ret < 0) fatal("could not create pipe...check fd limit");
if( maxpipedesc < pipeArr[i][0] ) maxpipedesc = pipeArr[i][0];
FD_SET(pipeArr[i][0],&readset)

Jakos nie dotarło, ze pipe inaczej zwraca deskryptory :) (nie odpalałem man 2 pipe), ale kurcze skoro juz poznałes sposób, to mimo błedu powinienes sam resztę rozwiazac i sprawdzić prawidłowy uchwyt

1 użytkowników online, w tym zalogowanych: 0, gości: 1