# ptQueue Сищная либа для "потокобезопасных" очередей на односвязном списке для ситуаций когда есть только один писатель. После передачи объекта в очередь, писатель теряет владение объектом и его управление переходит к читателю/читателям. Как использовать: ```C #include // для 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; } ```