Add readme
This commit is contained in:
97
README.md
Normal file
97
README.md
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# ptQueue
|
||||||
|
Сищная либа для "потокобезопасных" очередей на односвязном списке для ситуаций когда есть только один писатель.
|
||||||
|
После передачи объекта в очередь, писатель теряет владение объектом и его управление переходит к читателю/читателям.
|
||||||
|
|
||||||
|
Как использовать:
|
||||||
|
```C
|
||||||
|
#include <stdlib.h> // для abort, malloc, free
|
||||||
|
|
||||||
|
#include "ptQueue.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char errbuf[1024];
|
||||||
|
|
||||||
|
|
||||||
|
ptQueue* q = ptQueueCreate(errbuf);
|
||||||
|
if(q == NULL)
|
||||||
|
{
|
||||||
|
// Случай когда нет памяти на инициализацию
|
||||||
|
printf("Failed to create out q: %s\n", errbuf);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 4096; i++)
|
||||||
|
{
|
||||||
|
int* payload = malloc(sizeof(int));
|
||||||
|
if(payload == NULL)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*payload = i;
|
||||||
|
|
||||||
|
int exitCode = ptQueuePush(q, payload, errbuf);
|
||||||
|
if(exitCode)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* При каждом push выполняется аллокация элемента очереди,
|
||||||
|
* может вернуть NULL
|
||||||
|
*/
|
||||||
|
printf("Unable to push: %s\n", errbuf);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сами записали - сами и прочитаем с самого начала
|
||||||
|
ptQueueElem* tailIn = q->haed;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
void* payload = atomic_load(&(tailIn->payload));
|
||||||
|
if(payload == NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Когда в очереди не осталось данных,
|
||||||
|
* в текущем хвосте *payload будет NULL,
|
||||||
|
* значит ждём новых данных
|
||||||
|
*/
|
||||||
|
microsecond_sleep(100);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int* code = payload;
|
||||||
|
|
||||||
|
if(*code == 4095)
|
||||||
|
{
|
||||||
|
free(payload);
|
||||||
|
// Дошли до последнего отправленного элемента, выходим
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Владение ушло от писателя,
|
||||||
|
* при этом после прочтения оно никому более не уйдёт,
|
||||||
|
* поэтому освобождаем память
|
||||||
|
*/
|
||||||
|
free(payload);
|
||||||
|
|
||||||
|
ptQueueElem* newTail = atomic_load(&(tailIn->nextEl));
|
||||||
|
if (newTail == NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* При push в текущий tail записывается
|
||||||
|
* сначала указатель на следующий элемент,
|
||||||
|
* после чего записывается *payload.
|
||||||
|
* Тут обрабатываем невозможную ситуацию
|
||||||
|
*/
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Больше некому прочитать этот элемент, удаляем
|
||||||
|
free(tailIn);
|
||||||
|
tailIn = newTail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
59
src/main.c
59
src/main.c
@@ -78,20 +78,6 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int* ii = malloc(sizeof(int));
|
|
||||||
if(ii == NULL)
|
|
||||||
{
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
*ii = 0;
|
|
||||||
|
|
||||||
int excode = ptQueuePush(qOut, ii, errbuf);
|
|
||||||
if(excode)
|
|
||||||
{
|
|
||||||
printf("Unable to push 0: %s\n", errbuf);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
ptQueueElem* tailIn = qIn->tail;
|
ptQueueElem* tailIn = qIn->tail;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@@ -108,22 +94,22 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
|
|
||||||
int* pass = malloc(sizeof(int));
|
int* pass = malloc(sizeof(int));
|
||||||
if(pass != NULL)
|
if(pass == NULL)
|
||||||
{
|
{
|
||||||
*pass = *code;
|
abort();
|
||||||
int excode = ptQueuePush(qOut, pass, errbuf);
|
|
||||||
if(excode)
|
|
||||||
{
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
*pass = *code;
|
||||||
if(*code == 0)
|
int excode = ptQueuePush(qOut, pass, errbuf);
|
||||||
|
if(excode)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(*code == 4095)
|
||||||
{
|
{
|
||||||
free(payload);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(payload);
|
|
||||||
ptQueueElem* newTail = atomic_load(&(tailIn->nextEl));
|
ptQueueElem* newTail = atomic_load(&(tailIn->nextEl));
|
||||||
if (newTail == NULL)
|
if (newTail == NULL)
|
||||||
{
|
{
|
||||||
@@ -131,8 +117,31 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
free(tailIn);
|
free(tailIn);
|
||||||
tailIn = newTail;
|
tailIn = newTail;
|
||||||
|
|
||||||
|
|
||||||
|
excode = ptQueuePush(qOut, payload, errbuf);
|
||||||
|
if(excode)
|
||||||
|
{
|
||||||
|
printf("Unable to push: %s\n", errbuf);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int* ii = malloc(sizeof(int));
|
||||||
|
if(ii == NULL)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*ii = 0;
|
||||||
|
|
||||||
|
int excode = ptQueuePush(qOut, ii, errbuf);
|
||||||
|
if(excode)
|
||||||
|
{
|
||||||
|
printf("Unable to push 0: %s\n", errbuf);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pthread_join(tid, NULL);
|
pthread_join(tid, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user