, . , , " , " (first in first out, FIFO), , , , , , , , , , . .
10.3 . , , Windows . , UNIX Pthreads, . , . 10.7 Windows.
10.4 10.5 , .
10.3. SynchObj.h: 2
/* .*/
/* */
/* . */
/* , */
/* " " " ". */
/* , . */
typedef struct queue_tag { /* . */
HANDLE q_guard; /* . */
HANDLE q_ne; /* . . ( " ".) */
HANDLE q_nf; /* . . ( " ".) */
volatile DWORD q_size; /* . */
volatile DWORD q_first; /* . */
volatile DWORD q_last; /* . */
volatile DWORD q_destroyed; /* . */
PVOID msg_array; /* q_size . */
} queue_t;
/* . */
DWORD q_initialize(queue_t *, DWORD, DWORD);
DWORD q_destroy(queue_t *);
DWORD q_destroyed(queue_t *);
DWORD q_empty(queue_t *);
DWORD q_full(queue_t *);
DWORD q_get(queue_t *, PVOID, DWORD, DWORD);
DWORD q_put(queue_t *, PVOID, DWORD, DWORD);
DWORD q_remove(queue_t *, PVOID, DWORD);
DWORD q_insert(queue_t *, PVOID, DWORD);
10.4 , q_initialize q_get, 10.3. , q_get q_put , q_remove q_insert, , . , .
|
|
q_empty q_full , .
PulseEvent ( ), , .
q_get q_put. , . , , , , .
, , C++, , ; 10.8.
10.4. QueueObj.:
/* 10. QueueObj.c. */
/* */
#include "EvryThng.h"
#include "SynchObj.h"
/* . */
DWORD q_get(queue_t *q, PVOID msg, DWORD msize, DWORD MaxWait) {
if (q_destroyed (q)) return 1;
WaitForSingleObject(q->q_guard, INFINITE);
while (q_empty(q)) {
SignalObjectAndWait(q->q_guard, q->q_ne, INFINITE, FALSE);
WaitForSingleObject(q->q_guard, INFINITE);
}
/* . */
q_remove(q, msg, msize);
/* , , . */
PulseEvent(q->q_nf);
ReleaseMutex(q->q_guard);
return 0;
}
DWORD q_put(queue_t *q, PVOID msg, DWORD msize, DWORD MaxWait) {
if (q_destroyed(q)) return 1;
WaitForSingleObject(q->q_guard, INFINITE);
while(q_full(q)) {
SignalObjectAndWait(q->q_guard, q->q_nf, INFINITE, FALSE);
WaitForSingleObject(q->q_guard, INFINITE);
}
/* . */
q_insert(q, msg, msize);
/* , ; .*/
PulseEvent (q->q_ne);
/* CV. */
ReleaseMutex(q->q_guard);
return 0;
}
DWORD q_initialize(queue_t *q, DWORD msize, DWORD nmsgs) {
/* , . */
/* . */
q->q_first = q->q_last = 0;
q->q_size = nmsgs;
q->q_destroyed = 0;
q->q_guard = CreateMutex(NULL, FALSE, NULL);
q->q_ne = CreateEvent(NULL, TRUE, FALSE, NULL);
q->q_nf = CreateEvent(NULL, TRUE, FALSE, NULL);
if ((q->msg_array = calloc(nmsgs, msize)) == NULL) return 1;
return 0; /* . */
}
DWORD q_destroy(queue_t *q) {
if (q_destroyed(q)) return 1;
/* , q_initialize. */
|
|
WaitForSingleObject(q->q_guard, INFINITE);
q->q_destroyed = 1;
free(q->msg_array);
CloseHandle(q->q_ne);
CloseHandle(q->q_nf);
ReleaseMutex(q->q_guard);
CloseHandle(q->q_guard);
return 0;
}
DWORD q_destroyed(queue_t *q) {
return (q->q_destroyed);
}
DWORD q_empty(queue_t *q) {
return (q->q_first == q->q_last);
}
DWORD q_full(queue_t *q) {
return ((q->q_last q->q_first) == 1 || (q->q_first == q->q_size-l && q->q_last == 0));
}
DWORD q_remove(queue_t *q, PVOID msg, DWORD msize) {
char *pm;
pm = (char *)q->msg_array;
/* ("") . */
memcpy(msg, pm + (q->q_first * msize), msize);
q->q_first = ((q->q_first + 1) % q->q_size);
return 0; /* . */
}
DWORD q_insert(queue_t *q, PVOID msg, DWORD msize) {
char *pm;
pm = (char *)q->msg_array;
/* ("") . */
if (q_full(q)) return 1; /* . */
memcpy(pm + (q->q_last * msize), msg, msize);
q->q_last = ((q->q_last + 1) % q->q_size);
return 0;
}