Thread: Non-Blocking read() in C

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    4

    Question Non-Blocking read() in C

    Hello everybody,

    I am trying to read data from an SD card. But the library function of read() is in blocking mode (synchronous). I want to modify this function into non-blocking mode (asynchronous) as it is waste of time waiting for the read operation to complete and I have to do other tasks as well. Its in C.

    Any tips and ideas on how to do it.

    Thank you in advance.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    This might be worth a shot:
    NAME
    fcntl - manipulate file descriptor

    SYNOPSIS
    #include <unistd.h>
    #include <fcntl.h>

    int fcntl(int fd, int cmd, ... /* arg */ );

    DESCRIPTION
    fcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd.

    fcntl() can take an optional third argument. Whether or not this argument is required is determined by cmd. The required argument type is indicated in parentheses
    after each cmd name (in most cases, the required type is long, and we identify the argument using the name arg), or void is specified if the argument is not required.

    ...
    F_GETFL (void)
    Read the file status flags; arg is ignored.

    F_SETFL (long)
    Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY,
    O_TRUNC) in arg are ignored. On Linux this command can only change the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags.
    Use F_GETFL to get the current flags, then or-in the O_NONBLOCK flag and F_SETFL.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2012
    Posts
    4
    Thank you for the reply. can you give me some example in context of c. I am not able to understand what you mean here

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Really?

    Gee, I thought you had more competence in C.
    I mean, you know what "non-blocking" is, and you have "other things to do".

    Your average noob would just be settling for getting anything at all to work.

    int fd = open("/path/to/my/sdcard",O_RDONLY);
    long flag = fcntl(fd, F_GETFL, 0 );
    fcntl(fd,F_SETFL,flag);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Assuming you're using Linux, you could use aio instead.

    It is extremely useful, and very easy to set up. For example, install a following signal handler
    Code:
    static void signal_handler(int signum, siginfo_t *info, void *context)
    {
        if (info->si_code == SI_ASYNCIO && info->si_value.sival_ptr != NULL)
            __sync_and_and_fetch((int *)info->si_value.sival_ptr, 0);
    }
    to a realtime signal, say SIGRTMIN+1. Then:
    Code:
        struct aiocb  operation;
        volatile int  pending;
        int result;
    
        operation.aio_fildes   = file descriptor;
        operation.aio_offset   = offset in file;
        operation.aio_buf      = pointer to data buffer;
        operation.aio_nbytes   = number of bytes to read/write;
        operation.aio_reqprio  = 0;
        operation.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
        operation.aio_sigevent.sigev_signo = SIGRTMIN+1;
        operation.aio_sigevent.sigev_value.sival_ptr = (int *)&pending;
    
        pending = 1;
    
        result = aio_read/write(&operation);
        if (result == -1) {
            /* Problem with the operation */
        }
    and the volatile int pending will turn to zero when the operation is complete, and you can reuse/discard the buffer. The actual transfer then occurs while your process does other work.

    If you cannot use or do not want to use AIO, I'd use a separate thread and blocking I/O. It results in simpler code (no complicated loops to intermingle read/write operations and other computation), and at least in Linux the extra cost of a thread that mostly sleeps is neglible. (Just remember to use a small per-thread stack for it. The default per-thread stack size is usually several megabytes, while 65536 bytes is more than enough.)

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    So, based on the cross-post, you're just looking for someone to write the code for you? Good luck with that. Maybe you should Google Beej's Guide and start reading.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with non-blocking IO
    By soundstep in forum C Programming
    Replies: 4
    Last Post: 01-12-2011, 07:31 AM
  2. Blocking Read, what is it?
    By Blasz in forum C Programming
    Replies: 2
    Last Post: 05-18-2010, 06:40 AM
  3. Serial port read() blocking
    By DavidDobson in forum C Programming
    Replies: 8
    Last Post: 04-01-2009, 10:45 AM
  4. Pros and Cons of blocking versus non-blocking sockets?
    By abachler in forum Networking/Device Communication
    Replies: 4
    Last Post: 05-08-2008, 06:52 AM
  5. non-blocking keyboard read
    By pppbigppp in forum Linux Programming
    Replies: 10
    Last Post: 01-17-2007, 06:51 AM