introducere
În acest document, vom examina modelul Windows Sockets. Comparăm interfața sincronă și asincronă API pentru ferestre și înțelegem de ce ar trebui să folosim un model asincron și modul în care extensia asincronă pentru prizele de ferestre oferă performanțe mai bune în Windows.
Sincronă Winsock
Interfațele API pentru sincronizări de ferestre sincronizate sunt modelate pe standardul Berkeley Sockets API. Compatibilitatea acestor două API-uri este foarte utilă. Mai ales când piese mai vechi de cod unix trebuie să fie portate la Windows.
În general, funcțiile sincrone ale ferestrelor API pentru ferestre sunt destinate programării procedurale utilizând mufe de blocare. Programele citesc și scriu în socluri într-un mod blocant, bazându-se în totalitate pe sistemul de operare. API-urile sincrone funcționează mai bine în sistemele multitasking orientate pe linii de comandă, cum ar fi Unix. Aceasta nu este cea mai bună alegere pentru Windows.
Pentru a aborda problemele de blocare într-un eveniment orientat pe Windows, API-ul Winsock simulează blocarea apelurilor prin utilizarea unui cârlig de blocare care conține o buclă de procesare a evenimentelor. Din păcate, această emulare de blocare a apelurilor către ferestre Sockets are unele limitări. În mod special, în acest moment poate fi activat numai un apel de blocare. Aceste restricții afectează în mod direct interfața utilizator a programului.
În ciuda faptului că programul blocat "se odihnește" până la apariția evenimentului de rețea așteptat, deoarece Windows este ocupat, acest lucru nu blochează cu adevărat. Ar fi mai corect să spunem că aceasta este o așteptare într-o buclă care procesează, de asemenea, mesaje Windows cum ar fi următorul exemplu:
Dacă mesajul ferestrei atribuit programului de blocare este plasat în coada de mesaje Windows, acesta este trecut la procedura de fereastră din program. Interfața cu utilizatorul aparținând programului rămâne activă. Utilizatorul poate selecta elementele de meniu și apasă tastele, care vor fi apoi trimise la program. Problemele pot apărea dacă utilizatorul selectează un element din meniu care cauzează o altă operație de rețea. Deoarece programul este deja în blocarea funcțiilor de rețea nu pot fi numite alte funcții de rețea, iar rezultatul unei încercări de a realiza o operație de rețea este o greșeală.
Pentru a preveni acest eveniment, program de Windows care utilizează sincron blocarea API, trebuie să se asigure că următoarea operație de rețea nu poate fi pornit până când programul este în modul de blocare. Programul trebuie să dezactivați toate elementele și intrarile de la tastatura de meniu, ceea ce poate duce la lansarea altor operațiuni de rețea, și este un proces complicat, mai ales în cazul în care o mulțime de moduri, sau dezactiva complet interfața cu utilizatorul pentru a primi mesaje de la mouse-ul și tastatura și mouse-ul de afișare - clepsidră.
Prima opțiune este mai preferabilă din punctul de vedere al utilizatorului. Utilizatorul nu va putea să pornească următoarea comandă de rețea, dar cel puțin restul din sistem va fi disponibil. Utilizatorul poate merge la un alt program rulat și poate continua să lucreze până când primul program așteaptă ca funcția de rețea să se termine. Cu toate acestea, nu este deloc ușor pentru un programator să îndeplinească această sarcină.
În cel de-al doilea caz, utilizatorul se află în fața cursorului - o clepsidră în așteptarea finalizării operațiunii de rețea, atunci când el putea la acel moment să efectueze o muncă utilă. Un mediu Windows multitasking este mai eficient decât o singură sarcină, deoarece rețeaua este ocupată.
În ambele cazuri, nu este posibilă efectuarea simultană a două operații de rețea în aceeași aplicație. Utilizatorul nu poate să trimită un mesaj în același timp și să verifice mesajele noi pe server.
Problema sincronizării ferestrelor API pentru ferestre poate fi rezolvată în două moduri. Ambele utilizează prize fără blocare. Prima metodă este aceea de a crea socluri non-blocante și funcția select () verifică starea soclului de interes. Apoi, din prize, datele și datele disponibile care pot fi plasate în coada de transmisie sunt citite și scrise. Cu toate acestea, pentru a evita problema de a bloca apelul, selectați) funcția (ar trebui să fie numit un parametru timeout egal cu zero, ceea ce duce la o operație non-blocare. Pur și simplu vorbind, funcția selectați () ar trebui să fie numit, astfel încât să nu pentru a bloca sistemul pentru a sprijini coadă de mesaje și, în același timp, să permită mesajele să ajungă la kernel-ul Windows. Pentru aceasta, trebuie să utilizați un cod care seamănă cu un cârlig de blocare:
În ciuda faptului că acest cod funcționează, este o decizie patetică. Timpul procesorului va fi ars, în timp ce nu se va efectua nimic eficient - funcția select () va fi executată în buclă. În acest fel, prea mult nu dispune de resurse de sistem și este inadecvat într-un sistem de operare Windows orientat spre evenimente.
O soluție mai eficientă pentru toate problemele de blocare a soclurilor este utilizarea extensiei asincrone a ferestrei API pentru ferestre.
Mulțumiri speciale: NiFi [UInC], Motrichuk Alexander, Dave Roberts.
Toate documentele și programele de pe acest site sunt colectate NUMAI în scopuri educaționale, nu suntem responsabili pentru eventualele consecințe care au survenit ca urmare a utilizării acestor materiale / programe. Utilizați toate cele de mai sus pe propriul risc.