# Use Asynchronous I/O

For external files, you can specify that I/O should be asynchronous. This specification will allow other statements to execute while an I/O statement is executing.

### Note

To execute a program that uses asynchronous I/O on Linux* or macOS systems, you must explicitly include one of the following compiler options when you compile and link your program:

- -threads

- -reentrancy threaded

- -qopenmp

On Windows* systems, no extra options are needed to execute a program that uses asynchronous I/O.

## Using the ASYNCHRONOUS Specifier

Asynchronous I/O is supported for all READ and WRITE operations to external files. However, if you specify asynchronous I/O, you cannot use variable format expressions in formatted I/O operations.

To allow asynchronous I/O for a file, first specify ASYNCHRONOUS='YES' in its OPEN statement, then do the same for each READ or WRITE statement that you want to execute in this manner.

Execution of an asynchronous I/O statement initiates a "pending" I/O operation, which can be terminated in the following ways:

- By an explicit WAIT (`initno`) statement, which performs a wait operation for the specified pending asynchronous data transfer operation

- By a CLOSE statement for the file

- By a file-positioning statement such as REWIND or BACKSPACE

- By an INQUIRE statement for the file

Use the WAIT statement to ensure that the objects used in the asynchronous data transfer statements are not prematurely deallocated. This action is especially important for local stack objects and allocatable objects that may be deallocated before completion of the pending operation. If you do not specify the wait operation, the program may terminate with an access violation error. The following example shows use of the WAIT statement:

    module mod
       real, allocatable :: X(:)
    end module mod
    subroutine sbr()
    use mod
    integer :: Y(500)
       !X and Y initialization
       allocate (X(500))
       call foo1(X, Y)
       !asynchronous writing
       open(1, asynchronous='yes')
       write(1, asynchronous='yes') X, Y
       !some computation
       call foo2()
       !wait operation
       wait(1)
       !X deallocation
       deallocate(X)
       !stack allocated object Y will be deallocated when the routine returns
    end subroutine sbr

You can use the INQUIRE statement with the keyword of ASYNCHRONOUS (ASYNCHRONOUS=specifier) to determine whether asynchronous I/O is allowed. If it is allowed, a value of YES is returned.

Additionally, you can use the INQUIRE statement with the keyword of PENDING (PENDING= specifier) to determine whether previously pending asynchronous data transfers are complete.

If an ID= specifier appears and the specified data transfer operation is complete, the variable specified by PENDING is assigned the value False and the INQUIRE statement performs a wait operation for the specified data transfer.

If the ID= specifier is omitted and all previously pending data transfer operations for the specified unit are complete, the variable specified by PENDING is assigned the value False and the INQUIRE statement performs wait operations for all previously pending data transfers for the specified unit.

Otherwise, the variable specified by PENDING is assigned the value True and no wait operations are performed. Previously pending data transfers remain pending.

## Using the ASYNCHRONOUS Attribute

A data attribute called ASYNCHRONOUS specifies that a variable may be subject to asynchronous input/output. Assigning this attribute to a variable allows certain optimizations to occur.

Parent topic: Fortran I/O

## See Also

Asynchronous Specifier (ASYNCHRONOUS=)
OPEN/ASYNCHRONOUS Specifier
INQUIRE/ASYNCHRONOUS Specifier
ASYNCHRONOUS Statement and Attributes