Condividi tramite


I/O sincrono e sovrapposti

LeReadFile, WriteFile, TransactNamedPipee Le funzioni 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 dispendiosa in termini di tempo. Quando una funzione viene eseguita in modo asincrono, viene restituita immediatamente, anche se l'operazione non è stata completata. Ciò consente l'esecuzione in background di un'operazione dispendiosa in termini di tempo mentre il thread chiamante è libero di eseguire altre attività.

L'uso dell'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 di attesa 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 di pipe.

Le operazioni sovrapposte consentono a una pipe di leggere e scrivere i dati contemporaneamente e per consentire a un singolo thread di eseguire operazioni di I/O simultanee su più handle di pipe. Ciò consente a un server di pipe a thread singolo di gestire le comunicazioni con più client pipe in modo efficiente. Per un esempio, vedere server named pipe usando undi I/O sovrapposto.

Affinché un server di 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

LeReadFile, WriteFile, TransactNamedPipee Le funzioni ConnectNamedPipe possono essere eseguite in modo asincrono solo se si abilita la modalità sovrapposta per l'handle di 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 strutturaOVERLAPPED specificata deve contenere un handle per un oggetto evento di reimpostazione manuale. Si tratta di un oggetto di sincronizzazione creato dalla funzioneCreateEvent. 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 di pipe consiste nell'usare una struttura OVERLAPPED separata con il proprio oggetto evento per ogni operazione. Per altre informazioni sugli oggetti evento, vedere Synchronization.

È 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 strutturaOVERLAPPEDOVERLAPPED e il completamento avviene con l'handle della pipe nello stesso modo di un'operazione asincrona di lettura o scrittura. Per altre informazioni, vedere porte di completamento I/O.

Quando ReadFile, WriteFile, TransactNamedPipee Le operazioni di 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 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 funzionegetOverlappedResultper determinare i risultati.

Uso delle routine di completamento

Le funzioni ReadFileEx e WriteFileExforniscono 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 finché il thread chiamato ReadFileEx e WriteFileEx avvia un'operazione di attesa avvisabile chiamando una delle funzioni di attesa avvisabili con il parametro fAlertable impostato su TRUE. In un'operazione di attesa avvisabile, le funzioni restituiscono anche quando un ReadFileEx o WriteFileEx routine di completamento viene accodata per l'esecuzione. 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 server named pipe tramite routine di completamento.