• Aucun résultat trouvé

Unit OS3: Concurrency Unit OS3: Concurrency

N/A
N/A
Protected

Academic year: 2022

Partager "Unit OS3: Concurrency Unit OS3: Concurrency"

Copied!
31
0
0

Texte intégral

(1)

Unit OS3: Concurrency Unit OS3: Concurrency

3.4. Windows APIs for Synchronization and 3.4. Windows APIs for Synchronization and

Inter-Process Communication

Inter-Process Communication

(2)

Copyright Notice Copyright Notice

© 2000-2005 David A. Solomon and Mark Russinovich

© 2000-2005 David A. Solomon and Mark Russinovich

These materials are part of the

These materials are part of the Windows Operating Windows Operating System Internals Curriculum Development Kit,

System Internals Curriculum Development Kit, developed by David A. Solomon and Mark E.

developed by David A. Solomon and Mark E.

Russinovich with Andreas Polze Russinovich with Andreas Polze

Microsoft has licensed these materials from David Microsoft has licensed these materials from David Solomon Expert Seminars, Inc. for distribution to Solomon Expert Seminars, Inc. for distribution to academic organizations solely for use in academic academic organizations solely for use in academic environments (and not for commercial use)

environments (and not for commercial use)

(3)

Roadmap for Section 3.4.

Roadmap for Section 3.4.

Windows API constructs for synchronization and Windows API constructs for synchronization and interprocess communication

interprocess communication Synchronization

Synchronization

Critical sections Critical sections

Mutexes Mutexes

Semaphores Semaphores Event objects Event objects

Synchronization through interprocess communication Synchronization through interprocess communication

Anonymous pipes Anonymous pipes

Named pipes Named pipes

Mailslots Mailslots

(4)

Critical Sections Critical Sections

Only usable from within the same process Only usable from within the same process

Critical sections are initialized and deleted but do not have handles Critical sections are initialized and deleted but do not have handles Only one thread at a time can be in a critical section

Only one thread at a time can be in a critical section

A thread can enter a critical section multiple times - however, the A thread can enter a critical section multiple times - however, the number of Enter- and Leave-operations must match

number of Enter- and Leave-operations must match

Leaving a critical section before entering it may cause deadlocks Leaving a critical section before entering it may cause deadlocks No way to test whether another thread is in a critical section

No way to test whether another thread is in a critical section

VOID InitializeCriticalSection( LPCRITICAL_SECTION sec );

VOID DeleteCriticalSection( LPCRITICAL_SECTION sec );

VOID EnterCriticalSection( LPCRITICAL_SECTION sec );

VOID LeaveCriticalSection( LPCRITICAL_SECTION sec );

BOOL TryEnterCriticalSection ( LPCRITICAL_SECTION sec );

(5)

Critical Section Example Critical Section Example

/* counter is global, shared by all threads */

/* counter is global, shared by all threads */

volatile int counter = 0;

volatile int counter = 0;

CRITICAL_SECTION crit;

CRITICAL_SECTION crit;

InitializeCriticalSection ( &crit );

InitializeCriticalSection ( &crit );

/* … main loop in any of the threads */

/* … main loop in any of the threads */

while (!done) { while (!done) {

_try { _try {

EnterCriticalSection ( &crit );

EnterCriticalSection ( &crit );

counter += local_value;

counter += local_value;

LeaveCriticalSection ( &crit );

LeaveCriticalSection ( &crit );

} }

_finally { LeaveCriticalSection ( &crit ); } _finally { LeaveCriticalSection ( &crit ); } }}

DeleteCriticalSection( &crit );

DeleteCriticalSection( &crit );

(6)

Synchronizing Threads with Synchronizing Threads with

Kernel Objects Kernel Objects

The following kernel objects can be used The following kernel objects can be used to synchronize threads:

to synchronize threads:

Processes Processes

Threads Threads

Files Files

Console input Console input

File change notifications File change notifications Mutexes

Mutexes

Events (auto-reset + manual-reset) Events (auto-reset + manual-reset) Waitable timers

Waitable timers

DWORD WaitForSingleObject( HANDLE hObject, DWORD dwTimeout );

DWORD WaitForMultipleObjects( DWORD cObjects,

LPHANDLE lpHandles, BOOL bWaitAll, DWORD dwTimeout );

(7)

Wait Functions - Details Wait Functions - Details

WaitForSingleObject():

WaitForSingleObject():

hObject specifies kernel object hObject specifies kernel object

dwTimeout specifies wait time in msec dwTimeout specifies wait time in msec

dwTimeout == 0 - no wait, check whether object is signaled dwTimeout == 0 - no wait, check whether object is signaled

dwTimeout == INFINITE - wait forever dwTimeout == INFINITE - wait forever

WaitForMultipleObjects():

WaitForMultipleObjects():

cObjects <= MAXIMUM_WAIT_OBJECTS (64) cObjects <= MAXIMUM_WAIT_OBJECTS (64)

lpHandles - pointer to array identifying these objects lpHandles - pointer to array identifying these objects

bWaitAll - whether to wait for first signaled object or all objects bWaitAll - whether to wait for first signaled object or all objects

Function returns index of first signaled object Function returns index of first signaled object

Side effects:

Side effects:

Mutexes, auto-reset events and waitable timers will be reset to Mutexes, auto-reset events and waitable timers will be reset to non-signaled state after completing wait functions

non-signaled state after completing wait functions

(8)

Mutexes Mutexes

Mutexes work across processes Mutexes work across processes

First thread has to call CreateMutex() First thread has to call CreateMutex()

When sharing a mutex, second thread (process) calls CreateMutex() When sharing a mutex, second thread (process) calls CreateMutex() or OpenMutex()

or OpenMutex()

fInitialOwner == TRUE gives creator immediate ownership fInitialOwner == TRUE gives creator immediate ownership

Threads acquire mutex ownership using WaitForSingleObject() or Threads acquire mutex ownership using WaitForSingleObject() or WaitForMultipleObjects()

WaitForMultipleObjects()

ReleaseMutex() gives up ownership ReleaseMutex() gives up ownership CloseHandle() will free mutex object CloseHandle() will free mutex object

HANDLE CreateMutex( LPSECURITY_ATTRIBUTE lpsa, BOOL fInitialOwner, LPTSTR lpszMutexName );

HANDLE OpenMutex( LPSECURITY_ATTRIBUTE lpsa, BOOL fInitialOwner, LPTSTR lpszMutexName );

BOOL ReleaseMutex( HANDLE hMutex );

(9)

Mutex Example Mutex Example

/* counter is global, shared by all threads */

/* counter is global, shared by all threads */

volatile int done, counter = 0;

volatile int done, counter = 0;

HANDLE mutex = CreateMutex( NULL, FALSE, NULL );

HANDLE mutex = CreateMutex( NULL, FALSE, NULL );

/* main loop in any of the threads, ret is local */

/* main loop in any of the threads, ret is local */

DWORD ret;

DWORD ret;

while (!done) { while (!done) {

ret = WaitForSingleObject( mutex, INFINITE );

ret = WaitForSingleObject( mutex, INFINITE );

if (ret == WAIT_OBJECT_0) if (ret == WAIT_OBJECT_0) counter += local_value;

counter += local_value;

else

else /* mutex was abandoned *//* mutex was abandoned */

break;

break; /* exit the loop *//* exit the loop */

ReleaseMutex( mutex );

ReleaseMutex( mutex );

}}

CloseHandle( mutex );

CloseHandle( mutex );

(10)

Comparison - POSIX mutexes Comparison - POSIX mutexes

POSIX pthreads specification supports mutexes POSIX pthreads specification supports mutexes

Synchronization among threads in same process Synchronization among threads in same process

Five basic functions:

Five basic functions:

pthread_mutex_init() pthread_mutex_init()

pthread_mutex_destroy() pthread_mutex_destroy() pthread_mutex_lock() pthread_mutex_lock() pthread_mutex_unlock() pthread_mutex_unlock() pthread_mutex_trylock() pthread_mutex_trylock()

Comparison:

Comparison:

pthread_mutex_lock() will block - equivalent to pthread_mutex_lock() will block - equivalent to WaitForSingleObject( hMutex );

WaitForSingleObject( hMutex );

pthread_mutex_trylock() is nonblocking (polling) - equivalent to pthread_mutex_trylock() is nonblocking (polling) - equivalent to WaitForSingleObject() with timeout == 0

WaitForSingleObject() with timeout == 0

(11)

Semaphores Semaphores

Semaphore objects are used for resource counting Semaphore objects are used for resource counting

A semaphore is signaled when count > 0 A semaphore is signaled when count > 0

Threads/processes use wait functions Threads/processes use wait functions

Each wait function decreases semaphore count by 1 Each wait function decreases semaphore count by 1 ReleaseSemaphore() may increment count by any value ReleaseSemaphore() may increment count by any value ReleaseSemaphore() returns old semaphore count

ReleaseSemaphore() returns old semaphore count

HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTE lpsa, LONG cSemInit, LONG cSemMax,

LPTSTR lpszSemName );

HANDLE OpenSemaphore( LPSECURITY_ATTRIBUTE lpsa, LONG cSemInit, LONG cSemMax,

LPTSTR lpszSemName );

HANDLE ReleaseSemaphore( HANDLE hSemaphore,

LONG cReleaseCount, LPLONG lpPreviousCount );

(12)

Events Events

Multiple threads can be released when a single event is signaled (barrier Multiple threads can be released when a single event is signaled (barrier

synchronization) synchronization)

Manual-reset event can signal several thread simultaneously; must be reset Manual-reset event can signal several thread simultaneously; must be reset manually

manually

PulseEvent() will release all threads waiting on a manual-reset event and PulseEvent() will release all threads waiting on a manual-reset event and automatically reset the event

automatically reset the event

Auto-reset event signals a single thread; event is reset automatically Auto-reset event signals a single thread; event is reset automatically fInitialState == TRUE - create event in signaled state

fInitialState == TRUE - create event in signaled state

HANDLE CreateEvent( LPSECURITY_ATTRIBUTE lpsa, BOOL fManualReset, BOOL fInititalState

LPTSTR lpszEventName );

BOOL SetEvent( HANDLE hEvent );

BOOL ResetEvent( HANDLE hEvent );

BOOL PulseEvent( HANDLE hEvent );

(13)

Comparison - Comparison -

POSIX condition variables POSIX condition variables

pthread’s condition variables are comparable to events pthread’s condition variables are comparable to events

pthread_cond_init() pthread_cond_init()

pthread_cond_destroy() pthread_cond_destroy()

Wait functions:

Wait functions:

pthread_cond_wait() pthread_cond_wait()

pthread_cond_timedwait() pthread_cond_timedwait()

Signaling:

Signaling:

pthread_cond_signal() - one thread pthread_cond_signal() - one thread

pthread_cond_broadcast() - all waiting threads pthread_cond_broadcast() - all waiting threads

No exact equivalent to manual-reset events

No exact equivalent to manual-reset events

(14)

Anonymous pipes Anonymous pipes

Half-duplex character-based IPC Half-duplex character-based IPC

cbPipe: pipe byte size; zero == default cbPipe: pipe byte size; zero == default

Read on pipe handle will block if pipe is empty Read on pipe handle will block if pipe is empty Write operation to a full pipe will block

Write operation to a full pipe will block Anonymous pipes are oneway

Anonymous pipes are oneway

BOOL CreatePipe( PHANDLE phRead, PHANDLE phWrite,

LPSECURITY_ATTRIBUTES lpsa, DWORD cbPipe )

main

prog1 prog2

pipe

(15)

I/O Redirection using I/O Redirection using

an Anonymous Pipe an Anonymous Pipe

/* Create default size anonymous pipe, handles are inheritable. */

/* Create default size anonymous pipe, handles are inheritable. */

if (!CreatePipe (&hReadPipe, &hWritePipe, &PipeSA, 0)) { if (!CreatePipe (&hReadPipe, &hWritePipe, &PipeSA, 0)) {

fprintf(stderr, “Anon pipe create failed\n”); exit(1);

fprintf(stderr, “Anon pipe create failed\n”); exit(1);

}}

/* Set output handle to pipe handle, create first processes. */

/* Set output handle to pipe handle, create first processes. */

StartInfoCh1.hStdInput = GetStdHandle (STD_INPUT_HANDLE);

StartInfoCh1.hStdInput = GetStdHandle (STD_INPUT_HANDLE);

StartInfoCh1.hStdError = GetStdHandle (STD_ERROR_HANDLE);

StartInfoCh1.hStdError = GetStdHandle (STD_ERROR_HANDLE);

StartInfoCh1.hStdOutput = hWritePipe;

StartInfoCh1.hStdOutput = hWritePipe;

StartInfoCh1.dwFlags = STARTF_USESTDHANDLES;

StartInfoCh1.dwFlags = STARTF_USESTDHANDLES;

if (!CreateProcess (NULL, (LPTSTR)Command1, NULL, NULL, TRUE, if (!CreateProcess (NULL, (LPTSTR)Command1, NULL, NULL, TRUE,

0, NULL, NULL, &StartInfoCh1, &ProcInfo1)) { 0, NULL, NULL, &StartInfoCh1, &ProcInfo1)) { fprintf(stderr, “CreateProc1 failed\n”); exit(2);

fprintf(stderr, “CreateProc1 failed\n”); exit(2);

}}

CloseHandle (hWritePipe);

CloseHandle (hWritePipe);

(16)

Pipe example (contd.) Pipe example (contd.)

/* Repeat (symmetrically) for the second process. */

/* Repeat (symmetrically) for the second process. */

StartInfoCh2.hStdInput = hReadPipe;

StartInfoCh2.hStdInput = hReadPipe;

StartInfoCh2.hStdError = GetStdHandle (STD_ERROR_HANDLE);

StartInfoCh2.hStdError = GetStdHandle (STD_ERROR_HANDLE);

StartInfoCh2.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);

StartInfoCh2.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);

StartInfoCh2.dwFlags = STARTF_USESTDHANDLES;

StartInfoCh2.dwFlags = STARTF_USESTDHANDLES;

if (!CreateProcess (NULL, (LPTSTR)targv, NULL, NULL,TRUE,/* Inherit if (!CreateProcess (NULL, (LPTSTR)targv, NULL, NULL,TRUE,/* Inherit handles. */

handles. */

0, NULL, NULL, &StartInfoCh2, &ProcInfo2)) { 0, NULL, NULL, &StartInfoCh2, &ProcInfo2)) {

fprintf(stderr, “CreateProc2 failed\n”); exit(3);

fprintf(stderr, “CreateProc2 failed\n”); exit(3);

}}

CloseHandle (hReadPipe);

CloseHandle (hReadPipe);

/* Wait for both processes to complete. */

/* Wait for both processes to complete. */

WaitForSingleObject (ProcInfo1.hProcess, INFINITE);

WaitForSingleObject (ProcInfo1.hProcess, INFINITE);

WaitForSingleObject (ProcInfo2.hProcess, INFINITE);

WaitForSingleObject (ProcInfo2.hProcess, INFINITE);

CloseHandle (ProcInfo1.hThread); CloseHandle (ProcInfo1.hProcess);

CloseHandle (ProcInfo1.hThread); CloseHandle (ProcInfo1.hProcess);

CloseHandle (ProcInfo2.hThread); CloseHandle (ProcInfo2.hProcess);

CloseHandle (ProcInfo2.hThread); CloseHandle (ProcInfo2.hProcess);

return 0;

return 0;

(17)

Named Pipes Named Pipes

Message oriented:

Message oriented:

Reading process can read varying-length messages precisely as Reading process can read varying-length messages precisely as sent by the writing process

sent by the writing process

Bi-directional Bi-directional

Two processes can exchange messages over the same pipe Two processes can exchange messages over the same pipe

Multiple, independent instances of a named pipe:

Multiple, independent instances of a named pipe:

Several clients can communicate with a single server Several clients can communicate with a single server using the same instance

using the same instance

Server can respond to client using the same instance Server can respond to client using the same instance

Pipe can be accessed over the network Pipe can be accessed over the network

location transparency location transparency

Convenience and connection functions Convenience and connection functions

(18)

Using Named Pipes Using Named Pipes

lpszPipeName:

lpszPipeName: \\.\pipe\[\\.\pipe\[path]pipenamepath]pipename

Not possible to create a pipe on remote machine (. – local machine) Not possible to create a pipe on remote machine (. – local machine) fdwOpenMode:

fdwOpenMode:

PIPE_ACCESS_DUPLEX, PIPE_ACCESS_INBOUND, PIPE_ACCESS_DUPLEX, PIPE_ACCESS_INBOUND, PIPE_ACCESS_OUTBOUND

PIPE_ACCESS_OUTBOUND fdwPipeMode:

fdwPipeMode:

PIPE_TYPE_BYTE or PIPE_TYPE_MESSAGE PIPE_TYPE_BYTE or PIPE_TYPE_MESSAGE

PIPE_READMODE_BYTE or PIPE_READMODE_MESSAGE PIPE_READMODE_BYTE or PIPE_READMODE_MESSAGE PIPE_WAIT or PIPE_NOWAIT (will ReadFile block?)

PIPE_WAIT or PIPE_NOWAIT (will ReadFile block?)

HANDLE CreateNamedPipe (LPCTSTR lpszPipeName, DWORD fdwOpenMode, DWORD fdwPipMode DWORD nMaxInstances, DWORD cbOutBuf, DWORD cbInBuf, DWORD dwTimeOut,

LPSECURITY_ATTRIBUTES lpsa );

Use same flag settings for all instances of a named pipe

(19)

Named Pipes (contd.) Named Pipes (contd.)

nMaxInstances:

nMaxInstances:

Number of instances, Number of instances,

PIPE_UNLIMITED_INSTANCES: OS choice based on resources PIPE_UNLIMITED_INSTANCES: OS choice based on resources dwTimeOut

dwTimeOut

Default time-out period (in msec) for WaitNamedPipe() Default time-out period (in msec) for WaitNamedPipe() First CreateNamedPipe creates named pipe

First CreateNamedPipe creates named pipe

Closing handle to last instance deletes named pipe Closing handle to last instance deletes named pipe Polling a pipe:

Polling a pipe:

Nondestructive – is there a message waiting for ReadFile Nondestructive – is there a message waiting for ReadFile

BOOL PeekNamedPipe (HANDLE hPipe,

LPVOID lpvBuffer, DWORD cbBuffer,

LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage);

(20)

Named Pipe Client Connections Named Pipe Client Connections

CreateFile with named pipe name:

CreateFile with named pipe name:

\\.\pipe\[

\\.\pipe\[path]pipenamepath]pipename

\\servername\pipe\[path]pipename\\servername\pipe\[path]pipename

First method gives better performance (local server) First method gives better performance (local server)

Status Functions:

Status Functions:

GetNamedPipeHandleState GetNamedPipeHandleState SetNamedPipeHandleState SetNamedPipeHandleState

GetNamedPipeInfo GetNamedPipeInfo

(21)

Convenience Functions Convenience Functions

WriteFile / ReadFile sequence:

WriteFile / ReadFile sequence:

BOOL TransactNamedPipe( HANDLE hNamedPipe, LPVOID lpvWriteBuf, DWORD cbWriteBuf, LPVOID lpvReadBuf, DWORD cbReadBuf, LPDOWRD lpcbRead, LPOVERLAPPED lpa);

• CreateFile / WriteFile / ReadFile / CloseHandle:

- dwTimeOut: NMPWAIT_NOWAIT, NMPWAIT_WIAT_FOREVER, NMPWAIT_USE_DEFAULT_WAIT

BOOL CallNamedPipe( LPCTSTR lpszPipeName, LPVOID lpvWriteBuf, DWORD cbWriteBuf, LPVOID lpvReadBuf, DWORD cbReadBuf, LPDWORD lpcbRead, DWORD dwTimeOut);

(22)

Server: eliminate the polling loop Server: eliminate the polling loop

lpo == NULL:

lpo == NULL:

Call will return as soon as there is a client connection Call will return as soon as there is a client connection

Returns false if client connected between CreateNamed Pipe call Returns false if client connected between CreateNamed Pipe call and ConnectNamedPipe()

and ConnectNamedPipe()

Use DisconnectNamedPipe to free the handle for connection from Use DisconnectNamedPipe to free the handle for connection from another client

another client

WaitNamedPipe():

WaitNamedPipe():

Client may wait for server‘s ConnectNamedPipe() Client may wait for server‘s ConnectNamedPipe()

Security rights for named pipes:

Security rights for named pipes:

GENERIC_READ, GENERIC_WRITE, SYNCHRONIZE GENERIC_READ, GENERIC_WRITE, SYNCHRONIZE

BOOL ConnectNamedPipe (HANDLE hNamedPipe, LPOVERLAPPED lpo );

(23)

Comparison with UNIX Comparison with UNIX

UNIX FIFOs are similar to a named pipe UNIX FIFOs are similar to a named pipe

FIFOs are half-duplex FIFOs are half-duplex

FIFOs are limited to a single machine FIFOs are limited to a single machine

FIFOs are still byte-oriented, so its easiest to use fixed-size records FIFOs are still byte-oriented, so its easiest to use fixed-size records in client/server applications

in client/server applications

Individual read/writes are atomic Individual read/writes are atomic

A server using FIFOs must use a separate FIFO for each client‘s A server using FIFOs must use a separate FIFO for each client‘s response, although all clients can send requests via a single, well response, although all clients can send requests via a single, well known FIFO

known FIFO

Mkfifo() is the UNIX counterpart to CreateNamedPipe() Mkfifo() is the UNIX counterpart to CreateNamedPipe() Use sockets for networked client/server scenarios

Use sockets for networked client/server scenarios

(24)

Client Example using Named Pipe Client Example using Named Pipe

WaitNamedPipe (ServerPipeName, NMPWAIT_WAIT_FOREVER);

WaitNamedPipe (ServerPipeName, NMPWAIT_WAIT_FOREVER);

hNamedPipe = CreateFile (ServerPipeName, GENERIC_READ | GENERIC_WRITE, hNamedPipe = CreateFile (ServerPipeName, GENERIC_READ | GENERIC_WRITE,

0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hNamedPipe == INVALID_HANDLE_VALUE) { if (hNamedPipe == INVALID_HANDLE_VALUE) {

fptinf(stderr, Failure to locate server.\n"); exit(3);

fptinf(stderr, Failure to locate server.\n"); exit(3);

}}

/* Write the request. */

/* Write the request. */

WriteFile (hNamedPipe, &Request, MAX_RQRS_LEN, &nWrite, NULL);

WriteFile (hNamedPipe, &Request, MAX_RQRS_LEN, &nWrite, NULL);

/* Read each response and send it to std out. */

/* Read each response and send it to std out. */

while (ReadFile (hNamedPipe, Response.Record, MAX_RQRS_LEN, &nRead, NULL)) while (ReadFile (hNamedPipe, Response.Record, MAX_RQRS_LEN, &nRead, NULL))

printf ("%s", Response.Record);

printf ("%s", Response.Record);

CloseHandle (hNamedPipe);

CloseHandle (hNamedPipe);

return 0;

return 0;

(25)

Server Example Using a Named Server Example Using a Named Pipe Pipe

hNamedPipe = CreateNamedPipe (SERVER_PIPE, PIPE_ACCESS_DUPLEX, hNamedPipe = CreateNamedPipe (SERVER_PIPE, PIPE_ACCESS_DUPLEX,

PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT, PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT, 1, 0, 0, CS_TIMEOUT, pNPSA);

1, 0, 0, CS_TIMEOUT, pNPSA);

while (!Done) { while (!Done) {

printf ("Server is awaiting next request.\n");

printf ("Server is awaiting next request.\n");

if (!ConnectNamedPipe (hNamedPipe, NULL) if (!ConnectNamedPipe (hNamedPipe, NULL)

|| !ReadFile (hNamedPipe, &Request, RQ_SIZE, &nXfer, NULL)) {

|| !ReadFile (hNamedPipe, &Request, RQ_SIZE, &nXfer, NULL)) { fprintf(stderr, “Connect or Read Named Pipe error\n”); exit(4);

fprintf(stderr, “Connect or Read Named Pipe error\n”); exit(4);

}}

printf( “Request is: %s\n", Request.Record);

printf( “Request is: %s\n", Request.Record);

/* Send the file, one line at a time, to the client. */

/* Send the file, one line at a time, to the client. */

fp = fopen (File, "r");

fp = fopen (File, "r");

while ((fgets (Response.Record, MAX_RQRS_LEN, fp) != NULL)) while ((fgets (Response.Record, MAX_RQRS_LEN, fp) != NULL))

WriteFile (hNamedPipe, &Response.Record, WriteFile (hNamedPipe, &Response.Record,

(strlen(Response.Record) + 1) * TSIZE, &nXfer, NULL);

(strlen(Response.Record) + 1) * TSIZE, &nXfer, NULL);

fclose (fp);

fclose (fp);

DisconnectNamedPipe (hNamedPipe);

DisconnectNamedPipe (hNamedPipe);

}} /* End of server operation. *//* End of server operation. */

(26)

Windows IPC - Mailslots Windows IPC - Mailslots

Broadcast mechanism:

Broadcast mechanism:

One-directional One-directional

Mutliple writers/multiple readers (frequently: one-to-many comm.) Mutliple writers/multiple readers (frequently: one-to-many comm.) Message delivery is unreliable

Message delivery is unreliable

Can be located over a network domain Can be located over a network domain

Message lengths are limited (w2k: < 426 byte) Message lengths are limited (w2k: < 426 byte) Operations on the mailslot:

Operations on the mailslot:

Each reader (server) creates mailslot with CreateMailslot() Each reader (server) creates mailslot with CreateMailslot() Write-only client opens mailslot with CreateFile() and

Write-only client opens mailslot with CreateFile() and

uses WriteFile() – open will fail if there are no waiting readers uses WriteFile() – open will fail if there are no waiting readers Client‘s message can be read by all servers (readers)

Client‘s message can be read by all servers (readers) Client lookup:

Client lookup: \\*\mailslot\mailslotname\\*\mailslot\mailslotname

Client will connect to every server in network domain Client will connect to every server in network domain

Mailslots bear some nasty implementation details;

they are almost never used

(27)

Locate a server via mailslot Locate a server via mailslot

hMS = CreateMailslot(

“\\.\mailslot\status“);

ReadFile(hMS, &ServStat);

/* connect to server */

hMS = CreateMailslot(

“\\.\mailslot\status“);

ReadFile(hMS, &ServStat);

/* connect to server */

App client 0

App client n

Mailslot Servers

While (...) { Sleep(...);

hMS = CreateFile(

“\\.\mailslot\status“);

...

WriteFile(hMS, &StatInfo }

App Server

Mailslot Client

Message is sent periodically

(28)

Creating a mailslot Creating a mailslot

lpszName points to a name of the form lpszName points to a name of the form

\\.\mailslot\[path]name

\\.\mailslot\[path]name

Name must be unique; mailslot is created locally Name must be unique; mailslot is created locally

cbMaxMsg is msg size in byte cbMaxMsg is msg size in byte dwReadTimeout

dwReadTimeout

Read operation will wait for so many msec Read operation will wait for so many msec

0 – immediate return 0 – immediate return

MAILSLOT_WAIT_FOREVER – infinite wait MAILSLOT_WAIT_FOREVER – infinite wait

HANDLE CreateMailslot(LPCTSTR lpszName, DWORD cbMaxMsg,

DWORD dwReadTimeout,

LPSECURITY_ATTRIBUTES lpsa);

(29)

Opening a mailslot Opening a mailslot

CreateFile with the following names:

CreateFile with the following names:

\\.\mailslot\[path]name

\\.\mailslot\[path]name - retrieve handle for local mailslot - retrieve handle for local mailslot

\\host\mailslot\[path]name

\\host\mailslot\[path]name - retrieve handle - retrieve handle for mailslot on specified host

for mailslot on specified host

\\domain\mailslot\[path]name

\\domain\mailslot\[path]name - returns handle representing all - returns handle representing all mailslots on machines in the domain

mailslots on machines in the domain

\\*\mailslot\[path]name

\\*\mailslot\[path]name - returns handle representing mailslots - returns handle representing mailslots on machines in the system‘s primary domain: max mesg. len:

on machines in the system‘s primary domain: max mesg. len:

400 bytes 400 bytes

Client must specifiy FILE_SHARE_READ flag Client must specifiy FILE_SHARE_READ flag

GetMailslotInfo() and SetMailslotInfo() are similar to their GetMailslotInfo() and SetMailslotInfo() are similar to their named pipe counterparts

named pipe counterparts

(30)

Further Reading Further Reading

Mark E. Russinovich and David A. Solomon, Microsoft Windows Mark E. Russinovich and David A. Solomon, Microsoft Windows Internals, 4th Edition, Microsoft Press, 2004.

Internals, 4th Edition, Microsoft Press, 2004.

Chapter 3 - System Mechanisms Chapter 3 - System Mechanisms Synchronization (from pp.149) Synchronization (from pp.149)

Named Pipes and Mailslots (from pp. 804) Named Pipes and Mailslots (from pp. 804)

Jeffrey Richter, Programming Applications for Microsoft Windows, Jeffrey Richter, Programming Applications for Microsoft Windows, 4th Edition, Microsoft Press, September 1999.

4th Edition, Microsoft Press, September 1999.

Chapter 10 - Thread Synchronization Chapter 10 - Thread Synchronization

Critical Sections, Mutexes, Semaphores, Events (from pp. 315) Critical Sections, Mutexes, Semaphores, Events (from pp. 315)

Johnson M. Hart, Win32 System Programming: A Windows® 2000 Johnson M. Hart, Win32 System Programming: A Windows® 2000 Application Developer's Guide, 2nd Edition, Addison-Wesley, 2000.

Application Developer's Guide, 2nd Edition, Addison-Wesley, 2000.

(31)

Source Code References Source Code References

Windows Research Kernel sources Windows Research Kernel sources

\base\ntos\ke – primitive kernel support

\base\ntos\ke – primitive kernel support

eventobj.c - Event object eventobj.c - Event object mutntobj.c – Mutex object mutntobj.c – Mutex object

semphobj.c – Semaphore object semphobj.c – Semaphore object timerobj.c, timersup.c – Timers timerobj.c, timersup.c – Timers wait.c, waitsup.c – Wait support wait.c, waitsup.c – Wait support

\base\ntos\ex – executive object (layered on kernel support)

\base\ntos\ex – executive object (layered on kernel support)

Event.c – Event object Event.c – Event object Mutant.c – Mutex object Mutant.c – Mutex object

Semphore.c – Semaphore object Semphore.c – Semaphore object Timer.c – Timer object

Timer.c – Timer object

\base\ntos\inc\ke.h, ex.h – structure/type definitions

\base\ntos\inc\ke.h, ex.h – structure/type definitions

Références

Documents relatifs

The class of languages accepted by nondeterministic finite-delay machines with a single tape of one of the three types is exactly the semiAFL (family of languages closed

Indeed, recently, several self-stabilizing algorithms which work under a distributed unfair daemon have been shown to have an exponential stabilization time in moves in the worst

We shall in fact construct special classes of probabilistic event structure that are adequate models of probabilistic distributed concurrent systems: corresponding probabilities

Au cours de cette étude, nous avons principalement analysé la réponse électrique du capteur en fonction de la température et de la pression d'oxygène. Ces conditions de travail qui

In view of the anticipated significance of non-collinear spin structures, including skyrmions and domain-wall based structures, in future spintronic devices it remains to be

An interesting sub-class of hybrid systems is the systems with finite state jump which are linear continuous-time systems for which the state undergoes fi- nite jump discontinuities

dRTEC is a distributed implementation of RTEC in Spark Stream- ing using the Scala programming language. Like RTEC, dRTEC per- forms CE recognition by means of continuous

We analysed important features of EBSN that can affect the design of effective event recommenders and compared well known algorithms on real data collected from the popular EBSN