Windows internals http://www.microsoft.com/italy/msdn/studenti scoriani@microsoft.com.

Slides:



Advertisements
Presentazioni simili
Scheduling (Schedulazione) Susanna Pelagatti – Università di Pisa
Advertisements

Memoria Virtuale in Linux
Meccanismi di IPC Problemi classici di IPC
Gestione Input Output A. Ferrari.
Il Consolidamento di Servizi Virtual Server 2005 PierGiorgio Malusardi Evangelist - IT Professional Microsoft.
Il Sistema Operativo.
Massa Laura Mela Enrica
1 Processi e Thread Processi Thread Meccanismi di comunicazione fra processi (IPC) Problemi classici di IPC Scheduling Processi e thread in Unix Processi.
Gestione del processore
1 Processi e Thread Meccanismi di IPC, Inter Process Communication (1)
1 Processi e Thread Meccanismi di IPC (1). 2 Comunicazioni fra processi/thread Processi/thread eseguiti concorrentemente hanno bisogno di interagire per.
DLL: Dynamic Linking Library
Gestione dei Processi. I processi Un processo è unistanza di esecuzione di un programma. Consiste di –Un identificatore univoco (PID) –La handle table.
Comandi ai dispositivi di I/O + Si usano due metodi per mandare informazioni a un dispositivo: –Istruzioni specifiche di I/O –I/O mappato in memoria (memory.
1 System Call per Comunicazione tra Processi Pipe.
Scheduling in Linux (Kernel 2.6)
Sicurezza e Policy in Active Directory
Memoria virtuale Memoria virtuale – separazione della memoria logica dell’utente dalla memoria fisica. Solo alcune parti di un programma devono trovarsi.
Operating System Concepts
Realizzazione del file system
Sincronizzazione fra processi
Processi Concetto di processo Scheduling dei processi
INTRODUZIONE AI SISTEMI OPERATIVI
Threads: Sistemi Operativi I Corso di Laurea in Ingegneria Informatica
Struttura dei sistemi operativi (panoramica)
I Thread.
Software di base Il sistema operativo è un insieme di programmi che opera sul livello macchina e offre funzionalità di alto livello Es.organizzazione dei.
CAPITOLO 2 INTRODUZIONE AL LINGUAGGIO JAVA E ALL'AMBIENTE HOTJAVA.
3. Architettura Vengono descritte le principali componenti hardware di un calcolatore.
2) Sistemi operativi Lab. Calc. AA2004/05 - cap.2.
1 Obiettivi di Windows 2000 Portabilita: scritto in C le chiamate al processore sono isolate codice dipendente dalla piattaforma isolato Estensibilita:
Organizzazione della Memoria (Unix) Text contiene le istruzioni in linguaggio macchina del codice eseguibile, può essere condiviso in caso di processi.
Sincronizzazione fra thread
Sistemi Operativi GESTIONE DEI PROCESSI.
Sistemi Operativi GESTIONE DELLA MEMORIA CENTRALE.
Strutture dei sistemi di calcolo Funzionamento di un sistema di calcolo Struttura di I/O Struttura della memoria Gerarchia delle memorie Architetture di.
1 LINUX: struttura generale The layers of a UNIX system. User Interface.
1 Scheduling in Windows 2000 Un thread entra in modalità kernel e chiama lo scheduler quando: Si blocca su un oggetto di sincronizzazione (semaforo, mutex,
Il sistema operativo Vito Perrone
Concorrenza e Sincronizzazione di Thread e Processi
Sicurezza in Windows NT Fabrizio Inguglia. Tratteremo: Struttura generale di Windows NT 4 Gestione delle politiche di sicurezza.
INTRODUZIONE l sistema operativo è il primo software che lutente utilizza quando accende il computer; 1)Viene caricato nella memoria RAM con loperazione.
Seconda Università degli Studi di Napoli Facoltà di Economia Corso di Informatica Prof.ssa Zahora Pina.
1 Scheduling in Windows 2000 Un thread entra in modalità kernel e chiama lo scheduler quando: Si blocca su un oggetto di sincronizzazione (semaforo, mutex,
Processi e Thread Job: Insieme di processi che condividono quote e limiti. Processo: Contenitore di risorse (una lista di thread, una lista di handle e.
Il Sistema Operativo (1)
1 Lucidi delle esercitazioni di Sistemi di Elaborazione in Rete Università degli Studi della Calabria Corso di Laurea in Ingegneria Gestionale A.A. 2003/2004.
Sincronizzazione dei processi
Threads.
Sistema Operativo (Software di base)
Prima di iniziare… Durata attività: due lezioni frontali + una lezione laboratorio + compiti per casa Prerequisiti: elementi base architettura dei calcolatori.
I processi.
1 Gestione del Processore (Scheduling). 2 Scheduling dei processi È l’attività mediante la quale il sistema operativo effettua delle scelte tra i processi,
Gestione del Processore (Scheduling)
1 Gestione della Memoria. 2 Idealmente la memoria dovrebbe essere –grande –veloce –non volatile Gerarchia di memorie –Disco: capiente, lento, non volatile.
Politecnico di Milano © Domenico Barretta Processi concorrenti in Unix Docente Domenico Barretta Politecnico di Milano
Gestione del processore (Scheduler)
TW Asp - Active Server Pages Nicola Gessa. TW Nicola Gessa Introduzione n Con l’acronimo ASP (Active Server Pages) si identifica NON un linguaggio di.
Gestione della Memoria. Scenario 1 o più CPU Un certo quantitativo di memoria Una memoria di massa.
1 Input/Output. 2 Livelli del sottosistema di I/O Hardware Gestori delle interruzioni Driver dei dispositivi Software di sistema indipendente dal dispositivo.
1 Input/Output. 2 Livelli del sottosistema di I/O Hardware Gestori delle interruzioni Driver dei dispositivi Software di sistema indipendente dal dispositivo.
1 Processi e Thread Processi e thread in Windows 2000.
1 Gestione della Memoria Capitolo Introduzione alla gestione della memoria 4.2 Swapping 4.3 Memoria virtuale 4.4 Implementazione 4.5 Algoritmi di.
PiattaformePiattaformePiattaformePiattaforme Antonio Cisternino 28 Gennaio 2005 OpenSourceOpenSourceOpenSourceOpenSource e ProprietarieProprietarieProprietarieProprietarie.
1 Processi e Thread Scheduling (Schedulazione). 2 Scheduling Introduzione al problema dello Scheduling (1) Lo scheduler si occupa di decidere quale fra.
Sistemi operativi di rete Ing. A. Stile – Ing. L. Marchesano – 1/18.
1 Processi e Thread Processi Thread Meccanismi di comunicazione fra processi (IPC) Problemi classici di IPC Scheduling Processi e thread in Unix Processi.
1 Processi e Thread Processi Thread Meccanismi di comunicazione fra processi (IPC) Problemi classici di IPC Scheduling Processi e thread in Unix Processi.
1 1. Introduzione alla gestione della memoria 2. Swapping 3. Memoria virtuale 4. Implementazione 5. Algoritmi di sostituzione Gestione della Memoria.
INTRODUZIONE AI SISTEMI OPERATIVI. Introduzione Il software può essere diviso un due grandi classi: Il software può essere diviso un due grandi classi:
Transcript della presentazione:

Windows internals http://www.microsoft.com/italy/msdn/studenti scoriani@microsoft.com

Benvenuti Un giorno di full immersion nel kernel di Windows Architettura del kernel Come funziona Come sfruttarlo al meglio Come analizzare i problemi

Agenda Architettura kernel di Windows Gestione della memoria Processi Thread Thread pool Jobs Interprocess communication Overlapped I/O Domande & Risposte

Architettura kernel di Windows

MS Windows NT: obiettivi del progetto Compatibilità applicazioni Win32, Win16, MS-DOS, OS/2, POSIX Portabilità Ieri: piattaforma Intel, RISC Oggi: IA-32 (Pentium), IA-64 (Itanium) A breve: AMD-64 (Opteron) Robustezza Estendibilità Performance binaria, sorgente, file system

Portabilità Laptop Computer Personal Server Symmetric Multiprocessors

Architettura di MS Windows NT I/O Devices DMA/Bus Controller Timers Caches, Interrupts CPU Privileged Architecture Software Hardware Applications and Subsystems (User-Mode Instruction Set) I/O Manager Security Monitor Object Manager Local IPC Virtual Memory Process Device Drivers Kernel HAL GDI USER

Robustezza: Spazi di indirizzamento separati System Memory (2 GB) Per-Process Paged Non-paged Physical Addressing Range

Robustezza: User Mode e Privileged-Processor Mode applicazioni in esecuzione Accesso esclusivamente allo spazio di indirizzamento dei processi Divieto di accesso diretto all’hardware Privileged-Processor Mode Contiene il codice di sistema: executive, drivers, kernel e HAL “Trusted” Può eseguire qualsiasi istruzione Accesso all’intero spazio di indirizzamento

Robustezza: Security Per-User Permissions Auditing Access Access Control List (ACL) Auditing Access Quotas (sempre presente, non implementato fino a Windows 2000)

Robustezza: i sottosistemi User Mode Win32-Based Application POSIX OS/2 Subsystem Win32 Subsystem Local Procedure Call Executive Send Reply Privileged-Processor Mode

Applications and Subsystems (User-Mode Instruction Set) Estendibilità I/O Devices DMA/Bus Controller Timers Caches, Interrupts CPU Privileged Architecture Software Hardware Applications and Subsystems (User-Mode Instruction Set) I/O Manager Security Monitor Object Manager Local IPC Virtual Memory Process Device Drivers Kernel HAL GDI USER Jobs Timer Queue Encryption NTFS-5 NTFS FAT

Gli oggetti di NT (kernel objects) Process Thread Section File Access Token Event Semaphore Mutex Registry

Object model L’object model consente di: monitorare le risorse implementare la sicurezza condividere le risorse

Object: struttura interna Object Name Object Directory Security Descriptor Quota Charges Open Handle Counter Open Handle Database Permanent/Temporary Kernel/User Mode Type Object Pointer Object Body Type Object Header Object Attributes

Object: interfaccia esterna Funzioni Parametri comuni Createxxx Security attributes, inheritance, name Openxxx Security attributes, inheritance, name BOOL CloseHandle(hObject) BOOL DuplicateHandle(hSourceProcess, hSource, hTargetProcess, lphTarget, fdwAccess, fInherit, fdwOptions) Lo scope di un Object Handle è relativo a ogni singolo processo Durata di un oggetto

Struttura SECURITY_ATTRIBUTES typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES;

Security Detail Access Token Event Object Access Control List Security ID: LEES Group IDs: TEAM1 TEAM2 LOCAL INTERACTIVE WORLD Privileges: None . Security Descriptor Allow LEES Synchronize Modify State TEAM1 Access Token Event Object Access Control List

Architettura Windows NT/2000 Radici nel passato (VMS) Disegno modulare ed estendibile Pochi cambiamenti e molte ottimizzazioni dal kernel di Windows NT 3.1 a quello di Windows 2000 Modello ad oggetti, ma non object-oriented

Gestione della memoria (Memory Manager)

Gestione della memoria I processori iAPX86 Indirizzamenti real-mode e protected-mode Funzioni API Condivisione della memoria VLM – Very Large Memory AWE – Address Windowing Extension

I Processori Intel iAPX86 Tutti eseguono il boot in Real Mode Su 8088/8086 è l’unica possibilità Su 286 e successivi è necessario per compatibilità Dopo il boot 286 e successivi possono passare al protected mode Tutti hanno un’architettura segmentata

Indirizzamento in real-mode 15 15 : segment offset (shift left by 4 bits) 19 4 3 19 16 15 segment’s base address 0 0 0 0 0 0 0 0 effective address + 1 MB RAM 19 linear address 220 = 1MB

Real-mode Nessun meccanismo di protezione della memoria Diverse combinazioni segment:offset indirizzano la stessa locazione di memoria fisica Nessun supporto hardware nativo per una efficacie implementazione del multitasking Microsoft ha inventato una implementazione software del multitasking per Windows 1.x

Protected-mode (32 bit) : ? GDT LDT selector offset RAM BASE ACC. 15 2 1 31 : selector T I RPL offset GDT 15 16GB/ 64TB BASE ACC. LIMIT ACCESS x 8192 BA+SS ? 63 48 BA LDT 15 SEGMENT 1 BASE ACC. LIMIT ACCESS TI = Table Index RPL = Requestor Privilege Level GDT = Global Descriptors Table (64KB) LDT = Local Descriptors Table (64KB) BASE = BA = Base Address (32 bit) LIMIT = Limit (20 bit) = 1 MB ACC. = ACCESS = Access Byte (12 bit) SS = Segment Size x 8192 63 48 RAM G D A V L P DPL S TYPE Struttura Interna Access Byte G = 0  SS = Limit x 1 Byte = 1 MB G = 1  SS = Limit x 1 Page = Limit x 4KB = 4GB (G = Granularity Bit)

Protected-mode (32 bit) Se la granularità è una pagina (4KB), ciascun segmento è da 4GB e lo spazio di indirizzamento virtuale è di 64TB! Il descriptor è comunque compatibile con 16 bit PM L’architettura è comunque segmentata e limita la portabilità Tipicamente le piattaforme RISC non hanno architettura segmentata…

Eliminare la Segmentazione In Win95 e WinNT, il sistema operativo utilizza un solo segmento da 4GB In pratica, l’indirizzamento in Win32 è basato esclusivamente sull’offset (32 bit) L’indirizzamento appare lineare (o flat) Questo assicura la portabilità ad architetture non segmentate (es. RISC) Win32 indirizza fino a 4GB RAM fisica Tuttavia la strategia di implementazione è basata sulle Pagine La quantità minima di memoria allocabile è la pagina = 4KB

Perchè Paginare la Memoria Se l’offset fosse usato come un riferimento diretto alla locazione di memoria, lo spazio di indirizzamento virtuale coinciderebbe con la RAM fisica installata Per indirizzare 4GB virtuali, sarebbe necessario disporre di 4GB di RAM fisica in ogni sistema! La paginazione consente di simulare uno spazio di indirizzamento fisico da 4GB anche se la RAM fisica installata è <4GB Remapping della memoria fisica sulla memoria virtuale Paginazione su disco Exceptions generate dal processore e gestite dal sistema operativo

32 bit Offset in Win32 i386 PDE (10 bit) PTE (10 bit) OFFSET (12 bit) 31 22 21 12 11 PDE (10 bit) PTE (10 bit) OFFSET (12 bit) 20 bits 12 bits 20 bits 12 bits 4GB 1023 1023 PAGE 4KB Page Directory Page Table Win32 Process Context CR#3 i386 RAM PDE = Page Directory Entry PTE = Page Table Entry CR#3 = Control Register #3

Spazio di indirizzamento System Memory (2 GB) Per-Process Paged Non-paged Physical Addressing Range

Memoria virtuale R e s r v d Process Address Space Physical Memory Page Tables Physical Memory Invalid Process Address Space 2 GB Committed Pages R e s r v d

Page Directory, Page Table, Page Frame 4 MB 8 MB 12 MB 2 GB Directory 1024 Entries Table Paging File Byte Within Page 10 Bits 12 Bits Directory Index Table Index Valid Paged Invalid Virtual Address Space 4K Frame Physical Memory

Paging File Contiene Pagine scambiate dalla Memoria RAM al Disco Dimensione pagina: 4K o 8K Paging Policy

Page Commitment Process Address Space 2 GB Committed Pages R e s r v d

Copy-on-Write e Guard Pages Page 2 Copy Committed Memory Process 2 Virtual Process 1 (Read-Write) Section

Funzioni API: VirtualAlloc Manipolazione pagine virtuali o spazi di indirizzamento Lettura stato pagine virtuali o spazi di indirizzamento LPVOID VirtualAlloc(lpvAddress, cbSize, fdwAllocationType, fdwProtect) BOOL VirtualFree(lpAddress, cbSize, fdwFreeType) BOOL VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect) DWORD VirtualQuery(lpAddress, pmbiBuffer,cbLength) BOOL VirtualLock(lpvAddress, cbSize) BOOL VirtualUnlock(lpvAddress, cbSize)

Esempio: Uso di Funzioni VirtualXXX ... lpBase = VirtualAlloc (NULL, my_size, MEM_RESERVE, PAGE_NOACCESS); __try{ // an EXCEPTION_ACCESS_VIOLATION here // will be fixed by MyFilter if possible } __except (MyFilter (GetExceptionInformation())) { VirtualFree (lpBase, 0, MEM_RELEASE);

Gestione Heap Lo Heap è ottimizzato per allocare blocchi di memoria più piccoli senza l’overhead di pagina (4k o 8k) Ogni processo ha uno Heap di default E’ possibile allocare Heap privati La memoria allocata in uno heap può portare a fenomeni di frammentazione Sono Thread-Safe per default

Funzioni API: HeapAlloc Allocazione di un Heap privato HANDLE HeapCreate(flOptions, dwInitialSize, dwMaximumSize) BOOL HeapDestroy(hHeap) LPVOID HeapAlloc(hHeap, dwFlags, dwBytes) BOOL HeapFree(hHeap, dwFlags, lpMem) DWORD HeapSize(hHeap, dwFlags, lpMem) LPVOID HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes) Sono Thread-Safe per default

Funzioni API: LocalAlloc/GlobalAlloc Tutti i puntatori sono valori a 32 bit LocalAlloc e GlobalAlloc allocano memoria dallo stesso Heap GlobalAlloc garantisce allocazioni con allineamento a 16 bit HGLOBAL GlobalAlloc(fuFlags, cbBytes) HLOCAL LocalAlloc(fuFlags, cbBytes) Presenti solo per ragioni di compatibilità: richiamano HeapAlloc

Funzioni API: C Run-Time Library Le funzioni delle Standard C Run-Time Libraries possono essere usate (malloc, calloc, free, realloc, ...) Bilanciare chiamate malloc() con free(), senza mischiare con GlobalFree(), HeapFree() o altro

Memory-Mapped File I Memory-Mapped Files consentono di condividere la memoria tra processi diversi Sono l’equivalente Win32 dell’oggetto kernel Section

Viste di Memory-Mapped File PG.SYS File Physical Memory Views Sections

FileMapping: le cose ovvie Il file è mappato in memoria come se fosse effettivamente caricato Gli indirizzi di memoria necessari ad effettuare il mapping devono essere riservati Solo le pagine effettivamente utilizzate (a cui si accede in lettura o in scrittura attraverso puntatori di memoria) vengono effettivamente lette/scritte su disco Il Paging File usato come Memory Mapped File non rende persistenti le operazioni effettuate in memoria

File Mapping: le cose meno ovvie Tutte le operazioni di I/O su file avvengono come operazioni di file-mapping La cache dell’I/O Manager è integrata con il Memory Manager Tutte le volte che si apre un eseguibile (.EXE, .DLL, .OCX), il codice e le risorse non vengono caricate in memoria fino a che non sono realmente utilizzate (anche queste sono operazioni di file-mapping) Caricando più volte la stesso file EXE/DLL da processi diversi, la memoria fisica impegnata è sempre la stessa

CreateFileMapping e OpenFileMapping Crea un oggetto Section HANDLE CreateFileMapping(hFile, lpsa, fdwProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpszMapName) Apre un oggetto Section HANDLE OpenFileMapping(dwDesiredAccess, bInheritHandle, lpszMapName) Assegnando a hFile il valore –1 si usa il PagingFile

MapViewOfFile e UnmapViewOfFile LPVOID MapViewOfFile(hMapObject, fdwAccess, dwOffsetHigh, dwOffsetLow, cbMap) BOOL UnmapViewOfFile(lpBaseAddress) BOOL FlushViewOfFile(lpvBase, cbFlush) UnmapViewOfFile scrive tutti i cambiamenti su disco Lazy Writes su disco delle scritture in memoria E’ garantita la coerenza di viste differenti di un singolo oggetto Section

Usare Memory-Mapped File come Shared Memory Process 2 Virtual Memory Process 1 Committed Section View

Gestione della memoria Superare il muro dei 4Gb con Win32 Solo per i dati, non per il codice VLM – Very Large Memory Solo su Windows 2000 Advanced Server Solo per processori a 64 bit, ad oggi solo Alpha, che non supporta più Windows 2000 AWE – Address Windowing Extension Su tutte le versioni di Windows 2000 Per tutti i processori a 32 e 64 bit (Win64) Meno comodo da usare...

AWE – Address Windowing Extension Per tutti i processori e per tutte le versioni di Windows 2000 Memoria mappata nello spazio virtuale disponibile al processo (2Gb/3Gb) Non funziona con funzioni grafiche/video Granularità 4K/8K Il processo deve essere abilitato (diritto Lock Pages in Memory) Una zona allocata con AWE non può essere condivisa con altri processi

AWE – Funzioni AllocateUserPhysicalPages VirtualAlloc MapUserPhysicalPages FreeUserPhysicalPages AllocateUserPhysicalPages – Allocazione di memoria fisica con AWE VirtualAlloc – con parametro MEM_RESERVE or MEM_PHYSICAL riserva una spazio di indirizzi per mappare una zona allocata con AWE MapUserPhysicalPages – Map/Unmap della memoria fisica allocata con AllocateUserPhysicalPages ad uno spazio di indirizzi riservato con VirtualAlloc FreeUserPhysicalPages – Libera la memoria fisica allocata con AllocateUserPhysicalPages

Gestione della memoria Introduzione architetturale Funzioni API Memory mapped file Condivisione della memoria VLM & AWE

Processi

Cosa è un Processo? Un istanza di un programma in esecuzione Un processo possiede degli Oggetti Gli oggetti sono rappresentati dagli Handle Cosa distingue un processo da un altro? Handle table Memoria privata Windows Il processo è un insieme di thread, ed esiste fino a che contiene almeno un thread

Win32-Based Process Model . . . Access Token Virtual Address Space Description Object Table Thread x File y Section z Available Objects Handle 1 Handle 2 Handle 3

Object Handle Ogni Object Handle Tipi di Object Handle E’ valido solo nel contesto del proprio processo Può essere ereditato Mantiene un oggetto in vita nel sistema fino a che tutti gli handle allo stesso oggetto non sono chiusi Tipi di Object Handle Private: CreateMutex, OpenSemaphore, ... Duplicated: BOOL DuplicateHandle(...) Inherited: fInheritHandles a TRUE in CreateProcess Pseudo: GetCurrentProcess(), GetCurrentThread(), ...

Ciclo di vita di un Processo Un processo viene creato associando sempre un file eseguibile (.EXE), che è mappato in memoria ed eseguito Creando un processo viene creato un thread Il primo thread di un processo può essere chiamato thread principale, anche se la sua chiusura non determina necessariamente la fine del processo La run-time library del C termina il processo corrente se si esce dalla funzione main() con return, indipendentemente dalla presenza di altri thread

Creazione di un Processo BOOL CreateProcess(lpszImageName, lpszCommandLine, lpsaProcess, lpsaThread, fInheritHandles, fdwCreate, lpvEnvironment, lpszCurDir, lpsiStartInfo, lppiProcInfo) HANDLE OpenProcess(fdwAccess, fInherit, IDProcess)

Informazioni ritornate dalla creazione di un Processo typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION; Gli handle hProcess e hThread vanno sempre chiusi con CloseHandle(hObject) quando non sono più utilizzati E’ un errore frequente dimenticare questa operazione su entrambi gli handle restituiti!

Chiudere un Processo Chiusura normale Chiudere l’handle ad un processo VOID ExitProcess(uExitCode) Chiudere l’handle ad un processo BOOL CloseHandle(hObject) Chiusura immediata (e anomala) di un processo BOOL TerminateProcess(hProcess, uExitCode) La chiusura dell’ultimo thread di un processo implica una chiamata ad ExitProcess()

Funzioni API LPTSTR GetCommandLine(VOID) HANDLE GetCurrentProcess(VOID) DWORD GetCurrentProcessId(VOID) VOID GetStartupInfo(lpsi) HANDLE OpenProcess(fdwAccess, fInherit, IDProcess) DWORD GetEnvironmentVariable(lpszName, lpszValue, cchValue) BOOL SetEnvironmentVariable(lpszName, lpszValue) LPVOID GetEnvironmentStrings(VOID)

Interprocess Communication (IPC) IPC viene realizzata quando due o più processi condividono un oggetto Gli oggetti usati per IPC includono: Shared memory (section object) Files Semaphores Pipes / Mailslot Windows sockets I metodi di accesso condiviso sono gli stessi per molti oggetti di tipo diverso

Condivisione di oggetti Può avvenire in tre modi: BOOL DuplicateHandle(hSourceProcess, hSource, hTargetProcess, lphTarget, fdwAccess, fInherit, fdwOptions) Creando o aprendo un “Named Object” Ereditarietà

Condivisione di oggetti Gli oggetti condivisi sono handle diversi che puntano allo stesso oggetto kernel Thread x Process A Object Table Thread y File k Section z Kernel Objects Handle 1 Handle 2 Handle 3 Process B File w

Ereditarietà Access Token Process A Granted Access Inheritance Thread x File y Section z Available Objects Handle 1 Handle 2 Handle 3 Object Table Granted Access Inheritance

Ereditarietà Gli oggetti condivisi attraverso ereditarietà assumono lo stesso valore di Handle CreateProcess(…) Process A Object Table Thread y File k Section z Kernel Objects Handle 1 Handle 2 Handle 3 Process B Object Table Handle 1 Handle 2 Handle 3 Thread x

Controllare l’ereditarietà typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES; BOOL bInheritHandle;

Processi Achitettura Object Handle Ciclo di vita di un processo Condivisione di oggetti Ereditarietà

Thread

Cosa è un Thread? Un thread è un percorso di esecuzione all’interno di un processo Un thread accede a tutte le risorse del processo in cui è contenuto Il ThreadID contraddistingue un thread nel sistema operativo, indipendentemente dal processo ospitante Un thread esiste fino a che: il percorso di esecuzione termina viene chiuso con ExitThread viene chiuso/distrutto il processo ospitante

Preemptive vs. Cooperative Thread 2 Preemptive (Windows NT) Thread 1 Processor Done Task 2 Cooperative (Windows 3.1) Task 1 Time I/O or Idle Executing Involuntary Voluntary

Win32 Preemptive Multitasking Thread 1 Thread 2 Process A Process B Process C Process D Thread 3 Process E System Scheduler i386

Perché usare thread multipli? I thread sono più economici dei processi Per dividere task paralleli Per supportare la concorrenza Perché i thread comunicano più velocemente Per sfruttare Symmetric Multiprocessing

Thread Overhead Ogni thread Win32 ha un “gemello” nel sottosistema Host Ci sono due stack per ogni thread C’è un Hardware Context per thread C’è un insieme di variabili statiche delle C Run-Time Library per thread

Schedulazione dei Thread Lo Scheduler Win32 : Schedula soltanto thread E’ preemptive E’ basato sulle priorità

Scheduler Lo scheduler conosce solo i Thread Ogni Thread ha due livelli di priorità Priorità di base Priorità corrente La priorità corrente è analizzata per decidere quale thread eseguire Non spiegare troppo come viene usato il livello di priorità corrente, arrivano le slide più avanti.

Scheduler La priorità di base è funzione di due valori: Classe di priorità del processo Valore di priorità del thread La priorità corrente è dinamica (viene variata dallo scheduler), ma non scende mai al di sotto della priorità di base

Priorità di processi e thread IDLE BELOW_NORMAL NORMAL ABOVE_NORMAL HIGH REALTIME Thread IDLE LOWEST BELOW_NORMAL NORMAL ABOVE_NORMAL HIGHEST TIME_CRITICAL La combinazione di classe di priorità di processo e thread determina il valore di priorità di base del thread (tra 0 e 31)... NT non abbassa la priorirità di un thread al di sotto del valore di base definito.

Calcolo priorità di base dei thread Realtime Time Critical 31 Realtime Realtime Livelli 16-31 24 Realtime Idle 16 High Dynamic Time Critical 15 13 Above Normal Normal Dynamic Livelli 1-15 10 Below Normal 8 Idle 6 4 Dynamic Idle System Idle

Scheduler Logica di funzionamento dello scheduler Trova il thread attivo con priorità corrente più alta e lo esegue per un quantum Solo il thread non sospeso con la priorità più alta viene eseguito Se ci sono più thread con lo stesso livello, effettua un round-robin tra questi L’unico modo per eseguire thread a priorità più bassa è che i thread a priorità più alta vadano in stato di Wait (ad es. per operazioni di I/O) Note a lato: se al termine del quantum non ci sono cambiamenti in sospensioni e/o priorità, lo steso thread riceve nuovamente il quantum. In un sistema multiprocessore (SMP), possono verificarsi condizioni per cui su un processore non gira il thread al momento non sospeso con la priorità più alta.

Scheduler Impatto dello scheduler sui tempi di risposta Appena un thread a priorità più alta non è più sospeso, lo scheduler interrompe il thread in esecuzione e passa il controllo al thread con la priorità più alta La priorità di un thread non agisce quindi direttamente sulla percentuale di tempo di CPU assegnata

Priorità di processi e thread Variable Real-Time Real-Time Class High Class Normal Class Lo scheduler agisce solo in base al livello di priorità corrente del thread, che però cambia in continuazione (a parte i casi descritti più avanti). Notare che i processi “normali” hanno una priorità massima di 15; anche le applicazioni in Idle possono spostare un thread a quella priorità. Le priorità superiori a 11 possono causare, rallentamenti del sistema operativo; processi in Real-Time possono fermare servizi del sistema operativo come Flush della cache del disco, mouse, ecc. Idle Class 1 5 10 15 16 20 25 31

Scheduler Come fa Windows a funzionare? Il trucco è che la priorità corrente del thread è modificata continuamente dallo scheduler: I thread in attesa vengono premiati I thread che usano più CPU sono penalizzati L’applicazione in primo piano riceve un quantum più lungo Paragonare i thread ai lavori assegnati a chi lavora in un azienda: cambiano continuamente di priorità, e quello con la priorità più alta è l’unico a essere portato avanti, almeno fino a che non arriva un lavoro con una proprietà più alta. L’unica differenza tra un impiegato e lo scheduler di NT è che l’impiegato si stressa prima.

Scheduler Andamento del livello di priorità corrente nel tempo Priority Boost Quantum Decay Round-Robin at Base Base La priorità dinamica cambia come segue: ad ogni quantum la priorità scende, quando il thread va in wait si ha un Priority Boost. Notare che se il thread consuma molta CPU, comunque la sua priorità non scende mai al di sotto del livello di priorità base (tutti i quantum successivi fino ad una Wait restano al livello base di priorità). Run Wait Run Preempt Run Tempo

Scheduler Non voglio che lo scheduler cambi il livello di priorità corrente di un thread. Come faccio? Il livello di priorità corrente non scende mai al di sotto della priorità base. Un thread con priorità TIME_CRITICAL ha sempre il valore di priorità corrente 15 Tutti i valori superiori a 15 non sono mai modificati dinamicamente (processi in classe di priorità REALTIME)

Scheduler Non sono solo driver Priorità dinamiche Priorità statiche High Class Real-Time Class Above Normal Normal Class Non sono solo driver Below Normal Lo scheduler agisce solo in base al livello di priorità corrente del thread, che però cambia in continuazione (a parte i casi descritti più avanti). Notare che i processi “normali” hanno una priorità massima di 15; anche le applicazioni in Idle possono spostare un thread a quella priorità. Le priorità superiori a 11 possono causare, rallentamenti del sistema operativo; processi in Real-Time possono fermare servizi del sistema operativo come Flush della cache del disco, mouse, ecc. Idle Class 1 5 10 15 16 20 25 31

Controllare le priorità Un’applicazione può controllare la priorità dei suoi thread: CreateProcess parametro fdwCreate BOOL SetPriorityClass(hProcess, fdwPriority) BOOL SetThreadPriority(hThread, nPriority)

Creazione di un Thread La funzione Win32 per creare un thread è CreateThread Ogni libreria o ambiente di sviluppo ha delle funzioni specifiche per creare un thread: C/C++ RTL _beginthread(...) MFC AfxBeginThread(...) Se si usano le C-Run Time Libraries, specificare la versione multi-thread delle librerie nelle opzioni del progetto

C Run-Time Library

Funzioni di creazione dei Thread Win32 API HANDLE CreateThread( lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread) C Run-Time API unsigned long _beginthread( void (*start_address) (void *), unsigned stack_size, void *arglist)

Esempio CreateThread DWORD WINAPI CalculationThreadProc (LPVOID lpv) { printf(“CalculationThreadProc: Param=%d\n”, *((lpint)lpv); return 0; } DWORD main (void) { DWORD dwThreadId, dwThrdParam = 1; HANDLE hThread; hThread = CreateThread (NULL, //no security attributes 0, //default stack size CalculationThreadProc, //thread function &dwThrdParam, //thread function argument 0, //default creation flags &dwThreadId); //returns thread ID if (hThread == INVALID_HANDLE_VALUE) return 1; ... }

Esempio CalculationThreadProc typedef struct _threadargs { ... } THREADARGS, * LPTHREADARGS; DWORD WINAPI CalculationThreadProc ( LPVOID lpv) { LPTHREADARGS lpta = lpv; BOOL bRet; /*Do Calculation*/ return bRet; }

Thread IDs e Handles DWORD GetCurrentThreadId(VOID) DWORD GetCurrentProcessId(VOID) HANDLE CreateThread(lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread) HANDLE CreateRemoteThread(hProcess, lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread) HANDLE GetCurrentThread(VOID) HANDLE GetCurrentProcess(VOID)

Uscita da un Thread Funzioni API Win32 VOID ExitThread(dwExitCode) BOOL TerminateThread(hThread, dwExitCode) Funzioni API C Run-Time Libraries void _endthread(void)

Valori di uscita da un thread BOOL GetExitCodeProcess (hProcess, lpdwExitCode) BOOL GetExitCodeThread (hThread, lpdwExitCode) DWORD WaitForSingleObject(hObject, dwTimeout) DWORD WaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout)

evitare tecniche di polling Sincronizzazione Per scrivere codice efficiente è indispensabile... evitare tecniche di polling

Sincronizzazione Un thread che non deve aspettare un evento esterno deve andare in stato di Wait Se un thread deve aspettare che un altro thread abbia compiuto una certa operazione, si sfruttano gli oggetti kernel per la Sincronizzazione: Mutex Semaphore Event Critical Section

Attesa su Oggetti kernel Per sospendere un thread fino a che uno o più oggetti kernel non diventano “segnalati”, usare le funzioni di Wait: DWORD WaitForSingleObject( hObject, dwTimeout) DWORD WaitForMultipleObjects( cObjects, lphObjects, fWaitAll, dwTimeout) DWORD MsgWaitForMultipleObjects( cObjects, lphObjects, fWaitAll, dwTimeout, fdwWakeMask )

Scenario di sincronizzazione 1 Gestire in maniera efficiente l’input da una porta seriale Attende il prossimo carattere o il riempimento del buffer di input Legge e processa i caratteri Attende il prossimo carattere o il buffer Si usa l’oggetto Event, che è funzionalmente simile ad una variabile booleana

Event Objects Interprocess or Intraprocess Named or Unnamed HANDLE CreateEvent(lpsa, fManualReset, fInitialState, lpszEventName) HANDLE OpenEvent(fdwAccess, fInherit, lpszEventName) BOOL SetEvent(hEvent) BOOL ResetEvent(hEvent) BOOL PulseEvent(hEvent)

Uso di Event HANDLE hEvent = CreateEvent ( NULL, // no security TRUE, // event must be reset // manually FALSE, // initially nonsignaled NULL); // anonymous event StartTaskThatSignalsEventWhenDone (hEvent); // Do other processing. // Wait for event to be signaled; then reset it. WaitForSingleObject (hEvent, INFINITE); ResetEvent(hEvent); ... CloseHandle (hEvent);

Scenario di sincronizzazione 2 Proteggere strutture dati condivise, come code e liste in memoria condivisa, dal danneggiamento dovuto ad accessi concorrenti Si usa l’oggetto Mutex, che è un flag che coordina l’esecuzione di operazioni mutualmente esclusive Solo un thread può detenere un Mutex, gli altri thread vengono sospesi sulla Wait fino a che il Mutex non viene rilasciato

Mutex Objects Interprocess or Intraprocess Named or Unnamed Noncounting Mutual Exclusion HANDLE CreateMutex( lpsa, fInitialOwner, lpszMutexName) HANDLE OpenMutex( fdwAccess, fInherit, lpszMutexName) BOOL ReleaseMutex(hMutex)

Uso di Mutex if (!hMutex) // if we have not yet created the mutex... { // create mutex with creator having initial ownership hMutex = CreateMutex (NULL, TRUE, "Bob"); if (GetLastError() == ERROR_ALREADY_EXISTS) WaitForSingleObject (hMutex, INFINITE); } else WaitForSingleObject (hMutex, INFINITE); __try{ // use the resource protected by the mutex } __finally { ReleaseMutex (hMutex); } ... CloseHandle (hMutex);

Scenario di sincronizzazione 3 Porta per n-way Mutex Acquisisce una delle n risorse identiche da un pool di risorse disponibili Si usa l’oggetto Semaphore, che è simile ad un Mutex con un contatore Un Mutex è come un Semaphore che assume solo i valori 0 e 1; quando il Semaphore diventa 0, le chiamate a WaitFor... diventano sospensive, fino a che qualche thread non incrementa il valore del Semaphore

Semaphore Objects Interprocess or Intraprocess Named or Unnamed Counting HANDLE CreateSemaphore( lpsa, cSemInitial, cSemMax, lpszSemName) HANDLE OpenSemaphore( fdwAccess, fInherit, lpszSemName) BOOL ReleaseSemaphore( hSemaphore, cReleaseCount, lplPreviousCount)

Uso di Semaphore HANDLE hSem = CreateSemaphore ( NULL, // security 4, // initial count 4, // maximum count "Sally"); // global object name ... // Wait for any 1 of 4 resources to be available. WaitForSingleObject (hSem, INFINITE); __try{ // Use the semaphore. } __finally { ReleaseSemaphore (hSem, 1, &lPrevCount) }; CloseHandle (hSem);

Scenario di sincronizzazione 4 Sincronizzazione di diversi thread nello stesso processo con un oggetto Mutex il più velocemente possibile, con il minimo overhead (es. inserimento di un oggetto in una coda) Si usa l’oggetto Critical Section, che è un Mutex utilizzabile solo da thread di uno stesso processo

Critical Section Meccanismo veloce di condizione mutualmente esclusiva Memoria allocata dall’utente VOID InitializeCriticalSection(lpcsCriticalSection) VOID DeleteCriticalSection(lpcsCriticalSection) VOID EnterCriticalSection(lpcsCriticalSection) VOID LeaveCriticalSection(lpcsCriticalSection) Protegge l’accesso a dati condivisi da thread dello stesso processo

Uso di Critical Section CRITICAL_SECTION cs; InitializeCriticalSection (&cs); . . EnterCriticalSection (&cs); __try { // initialize the thread arguments. ta.hWnd = hWnd; ta.lpDIB = lpDIB; ta.rc = *lprc; ta.bFlags = bFlags; ta.pMP = pMP; } __finally { LeaveCriticalSection (&cs); } DeleteCriticalSection (&cs);

Thread e code mesaggi: Modello Win32 Application RIT Mouse Device Driver Keyboard Thread Raw Input Event Queues

Funzioni API per messaggi e thread BOOL PostMessage(hWnd, uMsg, wParam, lParam) BOOL GetMessage(lpmsg, hWnd, uMsgFilterMin, uMsgFilterMax) BOOL PostThreadMessage( dwThreadId, uMsg, wParam,lParam) BOOL PeekMessage(lpmsg, hWnd, uMsgFilterMin, uMsgFilterMax, fuRemoveMsg) LRESULT SendMessage(hWnd, uMsg, wParam, lParam) BOOL SendNotifyMessage(hWnd, uMsg, wParam, lParam) BOOL AttachThreadInput(idAttach, idAttachTo, fAttach) DWORD MsgWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout, fdwWakeMask )

Thread Definizione di thread Cooperative e preemptive multitasking Perchè usare thread multipli? Thread overhead Scheduler Creazione di un thread C Run-Time Library Oggetti per la sincronizzazione Thread e code di messaggi

Thread Pool

Thread Pool Insieme di Thread gestiti dal sistema Disponibili solo da Windows 2000 in poi Scenari affrontati: Accodare l’esecuzione asincrona di diverse funzioni Chiamare diverse funzioni periodicamente (senza WM_TIMER) Chiamare funzioni quando un oggetto kernel va in stato “segnalato” Chiamare una funzione quando una richiesta di I/O asincrono viene completata

Thread Pool – Scenario 1 Scenario: accodare l’esecuzione asincrona di diverse funzioni (ad es. una scrittura “posticipata”) Senza Thread Pool Creazione di un Thread, esecuzione della funzione, distruzione del Thread Con Thread Pool Una chiamata a QueueUserWorkItem

Thread Pool – Scenario 1 BOOL QueueUserWorkItem( LPTHREAD_START_ROUTINE pfnCallback, PVOID pvContext, ULONG Flags ); Valori di Flags: WT_EXECUTEDEFAULT WT_EXECUTEINIOTHREAD WT_EXECUTEINPERSISTENTIOTHREAD WT_EXECUTELONGFUNCTION

Thread Pool – Scenario 2 Scenario: chiamare diverse funzioni periodicamente Senza Thread Pool Un thread per ogni funzione, Sleep(x) tra una chiamata e l’altra WM_TIMER per ogni funzione Con Thread Pool Una chiamata a CreateTimerQueueTimer

Thread Pool – Scenario 2 CreateTimerQueue CreateTimerQueueTimer ChangeTimerQueueTimer DeleteTimerQueueTimer DeleteTimerQueueEx

Thread Pool – Scenario 2 BOOL CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue, WAITORTIMERCALLBACK Callback, PVOID Parameter, WORD DueTime, WORD Period, LONG Flags ); Valori di Flags: WT_EXECUTEINTIMERTHREAD WT_EXECUTEINIOTHREAD WT_EXECUTEINPERSISTENTIOTHREAD WT_EXECUTELONGFUNCTION

Thread Pool – Scenario 3 Scenario: eseguire una funzione quando un oggetto kernel diventa segnalato Senza Thread Pool Un thread per ogni funzione/oggetto, WaitForSingleObject prima della chiamata Un thread controlla più oggetti kernel con WaitForMultipleObjects... Con Thread Pool Chiamare RegisterWaitForSingleObject

Thread Pool – Scenario 3 RegisterWaitForSingleObject UnregisterWaitEx

Thread Pool – Scenario 3 BOOL RegisterWaitForSingleObject( PHANDLE phNewObject, HANDLE hObject, WAITORTIMERCALLBACK Callback, PVOID pvContext, ULONG dwMillisecs, ULONG dwFlags ); Valori di Flags: WT_EXECUTEDEFAULT WT_EXECUTEINWAITTHREAD WT_EXECUTEINIOTHREAD WT_EXECUTEINPERSISTENTIOTHREAD WT_EXECUTELONGFUNCTION WT_EXECUTEONLYONCE

Thread Pool – Scenario 4 Scenario: chiamare una funzione quando termina un’operazione di I/O asincrono Senza Thread Pool Creazione di un I/O completion port e gestione manuale di un thread pool Con Thread Pool Una chiamata a BindIoCompletionCallback

Thread Pool – Scenario 4 BOOL BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags ); Flags è riservato, deve valere sempre 0 Prototipo LPOVERLAPPED_COMPLETION_ROUTINE: VOID WINAPI OverlappedCompletionRoutine( DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped );

Thread Pool Esecuzione di funzioni asincrone Esecuzione periodica di funzioni Operazioni da eseguire quando un oggetto kernel diventa “segnalato” Operazioni da eseguire al termine di operazioni di I/O

Jobs

Job Gruppo di processi E’ un oggetto kernel Disponibile solo da Windows 2000 in poi Crea delle regole per i processi che contiene Può definire dei limiti su: Risorse del sistema Interfaccia utente Sicurezza Può monitorare l’attività dei processi

Job – Ciclo di vita Il Job viene creato “vuoto” Impostare proprietà del Job Un processo viene assegnato ad un Job La relazione Processo-Job è irreversibile Un processo figlio può nascere fuori dal Job del processo padre Se un Job viene terminato, tutti i suoi processi vengono terminati Il Job comunica con l’esterno con le I/O completion port (non segnala su Handle)

Job – Ciclo di vita Il nome associato al Job è accessibile fino a che ci sono handle aperti al Job Se tutti gli handle al Job vengono chiusi, il Job resta in vita ma non è più accessibile (verrà distrutto quando tutti i processi all’interno si saranno chiusi)

Job - Limiti Limiti sulle risorse di sistema: Process Priority Consumo CPU Working Set Size Consumo memoria Processor Affinity

Job - Limiti Limiti su interfaccia utente Accesso USER Handle (HWND, HMENU, ...) Creazione/Switch Desktop Modifica impostazioni video Modifica parametri di sistema Clipboard ExitWindows

Job - Limiti Limiti sulla security – Token utilizzabili: No Administrator Tutti i processi con un token uguale Solo token ristretti rispetto a quello del processo Filtro sui token (disabilitazione di alcuni diritti indipendentemente dall’utente impersonato)

Job - Monitoraggio Tempo CPU (kernel/user) Page Fault Numero processi (attivi/terminati) Attività di I/O (operazioni/byte) Elenco processi

Job - Funzioni CreateJobObject OpenJobObject AssignProcessToJobObject TerminateJobObject QueryInformationJobObject SetInformationJobObject UserHandleGrantAccess

Jobs Definizione di Job Ciclo di vita Limiti definibili Monitoraggio

Comunicazione tra processi (IPC – Interprocess Communication)

Comunicazione tra processi Per comunicare tra loro, due processi devono richiedere dei servizi al sistema operativo: Memory Mapped File (Shared Memory) Object Handles File su disco Socket, Named Pipe e Mailslot RPC (Remote Procedure Call)

Memory Mapped File Consente di condividere memoria tra processi diversi E’ una scelta adeguata quando più processi devono accedere contemporaneamente ad informazioni contenute in strutture dati di vaste dimensioni L’accesso simultaneo (almeno in scrittura) va protetto tramite meccanismi di sincronizzazione tra thread Non vi è una notifica istantanea della variazione di un dato da parte di un processo

Object Handle Più processi possono accedere ad uno stesso oggetto kernel E’ una tecnica indispensabile per condividere oggetti di sincronizzazione tra processi diversi

File su disco E’ un meccanismo che consente la condivisione di informazioni tra programmi in esecuzione anche su macchine diverse e con sistemi operativi diversi Le prestazioni e la scalabilità sono le più basse rispetto alle tecniche esaminate

Socket, Named Pipe, Mailslot Sono dei “canali” di comunicazione tra processi Si possono usare anche tra processi residenti su elaboratori diversi La trasmissione delle informazioni è sequenziale I dati inviati generano delle notifiche ai processi in ascolto: questo consente di evitare tecniche di polling anche su comunicazioni in rete

Socket Windows Sockets 2 è l’implementazione Microsoft dell’interfaccia di programmazione definita in “Berkely Sockets” Conosciuta come interfaccia di programmazione per TCP/IP, è utilizzabile anche per altri protocolli E’ il sistema ideale per implementare meccanismi di comunicazione su rete tra sistemi operativi diversi Supporta una comunicazione bidirezionale E’ un meccanismo client/server

Socket Il client può risiedere sulla stessa macchina del server, o su una macchina diversa Processo S1 Processo C1 Processo C2 Port 80 Port 1219 Port 1198 socket Computer A Computer B S1: Processo server C1, C2: Processi client

Named Pipe Meccanismo di comunicazione client-server Simile ad un socket, ma indipendente dal protocollo fisico Pipe Server: processo che crea una named pipe Pipe Client: processo che si connette ad una istanza di named pipe La named pipe ha un nome univoco per la macchina in cui è definita, ma possono esistere più istanze della stessa named-pipe Integra la “security” Modalità di funzionamento “message-mode” Server solo su NT/2000, Client su Win9x/NT/2000

Named Pipe Il client può risiedere sulla stessa macchina del server, o su una macchina diversa Processo S1 Processo C1 Processo C2 \\S1\pipe\Test named pipe Computer A Computer B S1: Processo server C1, C2: Processi client

Pipe Server Sequenza di funzioni API da chiamare: CreateNamedPipe ConnectNamedPipe ReadFile / WriteFile DisconnectNamedPipe CloseHandle

Pipe Client Sequenza di funzioni API da chiamare: CreateFile WriteNamedPipe SetNamedPipeHandleState ReadFile / WriteFile CloseHandle

Named Pipe: API speciali BOOL TransactNamedPipe(…) Esegue sequenzialmente WriteFile seguita da ReadFile Si usa sul client per semplificare il codice di esecuzione di transazioni sincrone BOOL CallNamedPipe(…) Esegue sequenzialmente WaitNamedPipe, CreateFile, TransactNamedPipe e CloseHandle Si usa sul client per semplificare il codice nel caso in cui per ogni transazione si vuole aprire e chiudere una connessione

Mailslot Meccanismo di comunicazione broadcast senza connessione Mailslot Server: processo che crea una mailslot e legge i dati ad essa inviati Mailslot Client: processo che scrive un messaggio su una mailslot Il nome di una mailslot è univoco per una macchina Nessuna gestione di “security” Modalità di funzionamento “message-mode” Server e Client su Win9x / NT / 2000

Mailslot Una macchina può ospitare solo una mailslot con lo stesso nome Processo C1 Processo S1 Processo S2 mailslot Computer A Computer B S1, S2: Processi server C1: Processo client \\.\mailslot\Test

Nomi delle Mailslot Creazione mailslot (server): \\.\mailslot\mailslotname Apertura mailslot per scrittura (client): \\ComputerName\mailslot\mailslotname \\DomainName\mailslot\mailslotname \\*\mailslot\mailslotname

Mailslot locali Il Mailslot server deve esistere quando il Mailslot client viene creato Un messaggio può essere lungo fino a 64K I messaggi inviati al server vengono ricevuti una volta I messaggi inviati vengono sicuramente ricevuti, ma non si sa se e quando vengono letti Possono esistere più client che scrivono sullo stesso server, se i client usano gli attributi FILE_SHARE_WRITE | FILE_SHARE_READ nella CreateFile()

Mailslot remote Deve esserci almeno un protocollo di rete attivo Il Mailslot client può essere creato in qualsiasi momento (anche se non esiste un Mailslot server) La scrittura da parte del Mailslot client non genera mai errori Un messaggio inviato ad un dominio può essere letto da più server Compatibilità garantita per messaggi fino a 425 byte Viene inviata una copia del messaggio per ogni protocollo di rete installato (il Mailslot server può ricevere più copie dello stesso messaggio)

Mailslot Server Sequenza di funzioni API da chiamare: CreateMailslot ReadFile CloseHandle

Mailslot Client Sequenza di funzioni API da chiamare: CreateFile WriteFile CloseHandle

Remote Procedure Call Consente di eseguire chiamate a funzioni presenti in processi diversi, anche su elaboratori diversi E’ basato sugli standard definiti da OSF (Open Software Foundation) DCE (Distributed Computing Environment) E’ indipendente dal protocollo di rete E’ la base di DCOM

Client Run-Time Library Remote Procedure Call Per ogni chiamata, avviene una transazione coordinata dal sistema operativo, per trasferire al “server” i parametri della funzione, e ricevere da esso i risultati Application Transport Client Stub Client Run-Time Library 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Client Server

Comunicazione tra processi Shared Memory Sockets Named Pipe Mailslot Remote Procedure Call

Operazioni di I/O (I/O Manager)

Windows NT I/O System Architecture Devices DMA/Bus Controller Timers Caches, Interrupts CPU Privileged Architecture Software Hardware Applications and Subsystems (User-Mode Instruction Set) I/O Manager Security Monitor Object Manager Local IPC Virtual Memory Process Device Drivers Kernel HAL GDI USER

Name Space unico per tutti i Device Environment Subsystem or DLL I/O System Services File System and Network Drivers I/O Manager Device Drivers User Mode Kernel Mode Video Monitor and Keyboard Printer Network Device Disk Drive Mouse Tape CD-ROM Drive

Link simbolici Usati per mappare nomi di Device MS-DOS al Name Space di Windows NT DWORD QueryDosDevice( lpDeviceName, lpTargetPath, ucchMax) BOOL DefineDosDevice( dwFlags, lpDeviceName, lpTargetPath) Esempio D: -> \DEVICE\HARDDISC0\PARTITION2

Cache Manager Cache di tutto l’I/O per default Incrementa le performance dei programmi che effettuano molte operazioni di I/O La dimensione della Cache è dinamica E’ un insieme di oggetti Section Ha il proprio spazio di indirizzamento (di sistema) Usa il Virtual Memory Manager per effettuare la paginazione

API per File I/O Si possono usare le seguenti API per accedere ai file: C Run-Time Library Windows 3.1 API (solo per compatibilità) Win32 API

Win95-Based Synchronous I/O Processing WriteFile(file_handle data, ...) WriteFile(file_handle data, ...) Returns Application Win32 Subsystem Call Windows NT Write File Service Return Data User Mode Kernel Mode Check Parameters Create IRP Call Device Driver Complete IRP Return I/O Manager Queue I/O to Device Device Driver Perform I/O Transfer Wait for Completion Device Time

Windows NT–Based Synchronous Processing WriteFile(file_handle data, ..., overlapped) . . . Application <Wait ends> Return I/O Status Call Windows NT Write File Service Win32 Subsystem User Mode Kernel Mode Check Parameters Create IRP Call Device Driver Wait(...) I/O Manager Set File Handle to Signaled State Queue I/O to Device Device Driver Return Handle Interrupt Perform I/O Transfer Interrupt for Service Device . . . Time

Asynchronous (Overlapped) I/O Processing WriteFile(file_handle data, ..., overlapped) . . . <Perform other work> Wait(file_handle) Application <Wait ends> Call Windows NT Write File Service Return I/O Pending Status Win32 Subsystem User Mode Kernel Mode Check Parameters Create IRP Call Device Driver Return I/O Manager Set File Handle to Signaled State Queue I/O to Device Device Driver Return Handle Interrupt Perform I/O Transfer Interrupt for Service Device . . . Time

Effettuare Overlapped I/O con Win32 Usare il flag FILE_FLAG_OVERLAPPED quando si apre un file con CreateFile() Effettuare un’operazione di I/O, e mettersi in Wait su: File handle, oppure Event object, oppure Una I/O completion callback

Esempio: Overlapped I/O usando Event Object HANDLE hFile; LPOVERLAPPED lpo; // create and initialize an OVERLAPPED structure lpo = calloc (sizeof(OVERLAPPED), 1); lpo->Offset = 0; lpo->hEvent = CreateEvent (NULL, TRUE, FALSE, NULL); hFile = CreateFile ("filename", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); // begin async io WriteFile(hFile, pBuffer, cbBuffer, &nBytesWritten, lpo); // wait for io to complete and get result GetOverlappedResult (hFile, lpo, &nBytesWritten, TRUE); // cleanup CloseHandle (lpo->hEvent); free (lpo);

I/O Completion Routine User-Mode Asynchronous Callback Non è veramente asincrona, perché può essere eseguita solo in corrispondenza di punti di controllo definiti (Control Points) Control Points ReadFileEx, WriteFileEx, WaitForSingleObjectEx, WaitForMultipleObjectsEx, SleepEx

Esempio: I/O Completion Routine VOID WINAPI lpfnIOCompletion ( DWORD dwError, DWORD cbWritten, LPOVERLAPPED lpo) { if (!dwError) lpo->Offset += cbWritten; } ... hFile = CreateFile ("filename", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); // create and initialize an OVERLAPPED structure lpo = calloc (sizeof(OVERLAPPED), 1); lpo->Offset = GetFileSize (hFile, NULL); // begin async io with callback WriteFileEx (hFile, pBuffer, cbBuffer, lpo, lpfnIOCompletion); ... // wait for callback to be called on i/o completion SleepEx (INFINITE, TRUE);

I/O Completion Port Basato su una coda (I/O Completion Port) di messaggi relativi alle operazioni di I/O asincrone completate (I/O Completion Packet) Uno o più thread (generalmente worker thread) possono prelevare messaggi dalla coda ed eseguire operazioni appropriate Si può controllare il numero massimo di thread attivi che possono processare I/O Completion Packet (eventuali altre richieste concorrenti sospendono il thread richiedente fino a che uno dei thread in esecuzione non completa l’elaborazione del Completion Packet prelevato)

Scatter-Gather I/O Meccanismo ad alte prestazioni per lettura/scrittura dati su file Disponibile su NT4.0 SP2 e successivi Usato da SQL Server Legge/scrive dati presenti in zone non contigue di memoria su zone di file contigue, sfruttando il DMA Granularità di pagina (4K / 8K) Funzioni API: ReadFileScatter(…) WriteFileGather(…)

Change Notification Oggetto kernel utilizzabile in funzioni di Wait per monitorare il cambiamento del contenuto di una directory FindFirstChangeNotification(…) FindNextChangeNotification(…) FindCloseChangeNotification(…) Nota bene: non si usa CloseHandle(…) per la chiusura dell’handle ottenuto con FindFirstChangeNotification(…)

I/O Manager Architettura I/O Manager Elaborazione sincrona dell’I/O Elaborazione asincrona dell’I/O I/O Completion Routine I/O Completion Port Change Notification

Riferimenti http://msdn.microsoft.com http://www.sysinternals.com

Altre Informazioni Dove posso ottenere maggiori informazioni www.sysinternals.com www.microsoft.com/msdn/italy/studenti www.ugidotnet.org Developer resources Microsoft Developer Network

Windows internals I vostri feedback sono importanti Compilate il modulo di valutazione Grazie della partecipazione scoriani@microsoft.com