Получите право доступа SYNCHRONIZE - PullRequest
1 голос
/ 27 ноября 2011

Я пишу простой многопоточный буфер. Его цель - хранить данные со звуковой карты, пока я не смогу их обработать. Он реализован в виде простого связанного списка (Элемент = элемент списка, DataQueue = фактический буфер, DataChunk = объект с данными):

class Element{
private:
    Element *next;
    DataChunk *data;
public:
    Element(DataChunk *data);
    ~Element();
    DataChunk *getData();
    Element *nextElement();
    void setNextElement(Element *nextElement);
};

class DataQueue{
private:
    int size;
    Element *top;
    Element *last;
    HANDLE lock;
public:
    DataQueue();
    void append(DataChunk *chunk);
    Element *cut(int *cutSize);
};

Element::Element(DataChunk *data){
    this->data = data;
    this->next = NULL;
}

Element::~Element(){
    delete data;
}

DataChunk *Element::getData(){
    return data;
}

Element *Element::nextElement(){
    return next;
}

void Element::setNextElement(Element *nextElement){
    this->next = nextElement;
}

DataQueue::DataQueue(){
    size = 0;
    top = NULL;
    last = NULL;
    lock = CreateEvent(NULL, TRUE, FALSE, TEXT("Lock"));
    if(lock == NULL){
        printf("Error code: %ld\n", GetLastError());
        exit(EXIT_FAILURE);
    }
}

void DataQueue::append(DataChunk *chunk){
    WaitForSingleObject(lock, INFINITE);
    SetEvent(lock);

    Element *element = new Element(chunk);
    if(top == NULL){
        top = element;
    }
    else{
        last->setNextElement(element);
    }
    last = element;

    ResetEvent(lock);
}

Element *DataQueue::cut(int *cutSize){
    WaitForSingleObject(lock, INFINITE);
    SetEvent(lock);

    Element *toReturn = top;
    *cutSize = size;
    top = NULL;
    last = NULL;
    size = 0;

    ResetEvent(lock);

    return toReturn;
}

Шаблон использования выглядит следующим образом: Аудио драйвер (ASIO) использует функции обратного вызова, чтобы уведомить меня, когда его буферы готовы к обработке. Это происходит много (дюжина раз в секунду). Но мне нужно обрабатывать данные только один раз в 5 секунд или около того. Поэтому я использую свой собственный буфер для хранения звуковых данных за 5 секунд. Драйвер создает свой собственный поток и выполняет функцию обратного вызова. Из этого потока я вызываю append () и добавляю данные из буферов устройств в мой буфер. Когда появляется фактический поток обработки, он обрезает буфер, получая первый элемент и сбрасывая буфер до 0 элементов.

Проблема заключается в синхронизации потоков. Функции cut () и access () являются взаимоисключающими. У меня есть Event HANDLE, и я жду этого события. У меня есть некоторый опыт работы с Java, и я совершенно новичок в этих Win32 API. Я делаю это правильно? Точно так же происходит сбой программы на WaitForSingleObject, возможно потому, что у меня нет права доступа SYNCHRONIZATION (c0000005). Как я могу установить поток, созданный драйвером? Будет ли это работать даже при наличии нескольких потоков обработки?

1 Ответ

1 голос
/ 29 ноября 2011

EnterCriticalSection добились цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...