Condividi tramite


I/O sincrono e sovrapposti

Le funzioni ReadFile, WriteFile, TransactNamedPipe e ConnectNamedPipe possono eseguire operazioni di input e output su una pipe in modo sincrono o asincrono. Quando una funzione viene eseguita in modo sincrono, non restituisce fino al completamento dell'operazione eseguita. Ciò significa che l'esecuzione del thread chiamante può essere bloccata per un periodo indefinito mentre attende il completamento di un'operazione che richiede molto tempo. Quando una funzione viene eseguita in modo asincrono, viene restituita immediatamente, anche se l'operazione non è stata completata. In questo modo è possibile eseguire in background un'operazione dispendiosa in termini di tempo, mentre il thread chiamante è libero di eseguire altre attività.

L'uso di I/O asincrono consente a un server di pipe di usare un ciclo che esegue i passaggi seguenti:

  1. Specificare più oggetti evento in una chiamata alla funzione wait e attendere che uno degli oggetti venga impostato sullo stato segnalato.
  2. Usare il valore restituito della funzione wait per determinare quale operazione sovrapposta è stata completata.
  3. Eseguire le attività necessarie per pulire l'operazione completata e avviare l'operazione successiva per l'handle della pipe. Ciò può comportare l'avvio di un'altra operazione sovrapposta per lo stesso handle pipe.

Le operazioni sovrapposte consentono a una pipe di leggere e scrivere dati contemporaneamente e per un singolo thread di eseguire operazioni di I/O simultanee su più handle di pipe. Ciò consente a un server pipe a thread singolo di gestire le comunicazioni con più client pipe in modo efficiente. Per un esempio, vedere Named Pipe Server using Overlapped I/O .For an example, see Named Pipe Server Using Overlapped I/O.

Affinché un server pipe usi operazioni sincrone per comunicare con più client, deve creare un thread separato per ogni client pipe in modo che uno o più thread possano essere eseguiti mentre altri thread sono in attesa. Per un esempio di server pipe multithreading che usa operazioni sincrone, vedere Server pipe multithreading.

Abilitazione dell'operazione asincrona

Le funzioni ReadFile, WriteFile, TransactNamedPipe e ConnectNamedPipe possono essere eseguite in modo asincrono solo se si abilita la modalità sovrapposta per l'handle pipe specificato e si specifica un puntatore valido a una struttura OVERLAPPED . Se il puntatore OVERLAPPED è NULL, il valore restituito della funzione può indicare erroneamente che l'operazione è stata completata. Pertanto, è consigliabile creare un handle con FILE_FLAG_OVERLAPPED e desiderare un comportamento asincrono, è consigliabile specificare sempre una struttura OVERLAPPED valida.

Il membro hEvent della struttura OVERLAPPED specificata deve contenere un handle per un oggetto evento di reimpostazione manuale. Si tratta di un oggetto di sincronizzazione creato dalla funzione CreateEvent . Il thread che avvia l'operazione sovrapposta usa l'oggetto evento per determinare al termine dell'operazione. Non è consigliabile usare l'handle pipe per la sincronizzazione quando si eseguono operazioni simultanee sullo stesso handle perché non è possibile sapere quale operazione ha causato la segnalazione dell'handle pipe. L'unica tecnica affidabile per eseguire operazioni simultanee sullo stesso handle pipe consiste nell'usare una struttura OVERLAPPED separata con il proprio oggetto evento per ogni operazione. Per altre informazioni sugli oggetti evento, vedere Sincronizzazione.

È anche possibile ricevere una notifica quando viene completata un'operazione sovrapposta usando le funzioni GetQueuedCompletionStatus o GetQueuedCompletionStatusEx . In questo caso, non è necessario assegnare l'evento di reimpostazione manuale nella struttura OVERLAPPED e il completamento avviene sull'handle pipe nello stesso modo di un'operazione di lettura o scrittura asincrona. Per altre informazioni, vedere Porte di completamento di I/O.

Quando le operazioni ReadFile, WriteFile, TransactNamedPipe e ConnectNamedPipe vengono eseguite in modo asincrono, si verifica una delle operazioni seguenti:

  • Se l'operazione viene completata al termine della funzione, il valore restituito indica l'esito positivo o negativo dell'operazione. Se si verifica un errore, il valore restituito è zero e la funzione GetLastError restituisce un valore diverso da ERROR_IO_PENDING.
  • Se l'operazione non è stata completata al termine della restituzione della funzione, il valore restituito è zero e GetLastError restituisce ERROR_IO_PENDING. In questo caso, il thread chiamante deve attendere il completamento dell'operazione. Il thread chiamante deve quindi chiamare la funzione GetOverlappedResult per determinare i risultati.

Utilizzo delle routine di completamento

Le funzioni ReadFileEx e WriteFileEx forniscono un'altra forma di I/O sovrapposta. A differenza delle funzioni ReadFile e WriteFile sovrapposte, che usano un oggetto evento per segnalare il completamento, le funzioni estese specificano una routine di completamento. Una routine di completamento è una funzione accodata per l'esecuzione al termine dell'operazione di lettura o scrittura. La routine di completamento non viene eseguita fino a quando il thread denominato ReadFileEx e WriteFileEx avvia un'operazione di attesa avvisabile chiamando una delle funzioni di attesa di avviso con il parametro fAlertable impostato su TRUE. In un'operazione di attesa avvisabile, le funzioni restituiscono anche quando viene accodata l'esecuzione di una routine di completamento ReadFileEx o WriteFileEx . Un server pipe può usare le funzioni estese per eseguire una sequenza di operazioni di lettura e scrittura per ogni client che vi si connette. Ogni operazione di lettura o scrittura nella sequenza specifica una routine di completamento e ogni routine di completamento avvia il passaggio successivo nella sequenza. Per un esempio, vedere Named Pipe Server Using Completion Routines.For an example, see Named Pipe Server Using Completion Routines.