获取同步访问权限



我正在写一个简单的多线程缓冲区。它的目的是保存声卡上的数据,直到我能处理它们。它被实现为一个简单的链表(Element = list Element, DataQueue =实际缓冲区,DataChunk = object with data):

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: %ldn", 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()函数是互斥的。我有事件句柄,我等待这个事件。我对Java有一些经验,对这些Win32 api完全陌生。我做得对吗?就像这样,程序在WaitForSingleObject上崩溃,可能是因为我没有同步访问权限(c0000005)。我如何将它设置为由驱动程序创建的线程?即使有多个处理线程,这也能工作吗?

EnterCriticalSection成功了。

最新更新