Question

Le code suivant:

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <aio.h>
#include <errno.h>

int main (int argc, char const *argv[])
{
  char name[] = "abc";
  int fdes;
  if ((fdes = open(name, O_RDWR | O_CREAT, 0600 )) < 0)
    printf("%d, create file", errno);

  int buffer[] = {0, 1, 2, 3, 4, 5};
  if (write(fdes, &buffer, sizeof(buffer)) == 0){
    printf("writerr\n");
  }

  struct aiocb aio;
  int n = 2;
  while (n--){
    aio.aio_reqprio = 0;
    aio.aio_fildes = fdes;
    aio.aio_offset = sizeof(int);
    aio.aio_sigevent.sigev_notify = SIGEV_NONE; 

    int buffer2;
    aio.aio_buf = &buffer2;
    aio.aio_nbytes = sizeof(buffer2);

    if (aio_read(&aio) != 0){
      printf("%d, readerr\n", errno);
    }else{
      const struct aiocb *aio_l[] = {&aio};
      if (aio_suspend(aio_l, 1, 0) != 0){
         printf("%d, suspenderr\n", errno);
      }else{
        printf("%d\n", *(int *)aio.aio_buf);
      }
    }
  }

  return 0;
}

fonctionne très bien sous Linux (Ubuntu 9.10, compilé avec -lrt), l'impression

1
1

Mais échoue sur OS X (10.6.6 et 10.6.5, je l'ai testé sur deux machines):

1
35, readerr

Est-ce possible que cela est dû à une erreur sur la bibliothèque OS X, ou que je fais quelque chose de mal?

Était-ce utile?

La solution

Vous devez appeler aio_return(2) exactement une fois pour chaque opération d'E / S asynchrone. D'après la note sur cette page de manuel, défaut de le faire fuira les ressources, et il provoque apparemment aussi votre problème. Une fois que vous appelez aio_suspend attendre le E / S complète, assurez-vous de aio_return d'appel pour obtenir le nombre d'octets lus, par exemple:.

const struct aiocb *aio_l[] = {&aio};
if (aio_suspend(aio_l, 1, 0) != 0)
{
  printf("aio_suspend: %s\n", strerror(errno));
}
else
{
  printf("successfully read %d bytes\n", (int)aio_return(&aio));
  printf("%d\n", *(int *)aio.aio_buf);
}

Gardez aussi à l'esprit ces remarques importantes de la aio_read(2) de l'homme (Souligné par l'auteur):

  

La structure de contrôle E / S asynchrones Bloquer pointé par aiocbp et la        tampon que l'élément de aiocbp->aio_buf de cette structure références doivent        restent valables jusqu'à ce que l'opération soit terminée. Pour cette raison, l'utilisation        variables automatiques (de la pile) pour ces objets est déconseillée .

     

Le tampon asynchrone de commande I / O aiocbp doit être mis à zéro avant la        appel aio_read() pour éviter de transmettre des informations contextuelles bogus au noyau.

Autres conseils

Essayez la mise à zéro struct aiocb aio?

Le manuel se lit comme suit:

RESTRICTIONS
[...]
     The asynchronous I/O control buffer aiocbp should be zeroed before the
     aio_read() call to avoid passing bogus context information to the kernel.
[...]
BUGS
     Invalid information in aiocbp->_aiocb_private may confuse the kernel.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top