获得同步访问权限
我正在编写一个简单的多线程缓冲区。它的目的是保存声卡中的数据,直到我可以处理它们。它被实现为一个简单的链表(Element = 列表元素,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 秒的声音数据。 Driver创建自己的线程并执行回调函数。从此线程中,我调用append()并将数据从设备缓冲区附加到我的缓冲区。当实际处理线程出现时,它通过获取第一个元素并将缓冲区重置为 0 个元素来剪切缓冲区。
问题是线程同步。 cut() 和 access() 函数是互斥的。我有事件句柄并等待此事件。我有一些 Java 经验,并且对这些 Win32 API 完全陌生。我做得对吗?就像这样,程序在 WaitForSingleObject 上崩溃,可能是因为我没有 SYNCHRONIZATION 访问权限(c0000005)。如何将其设置为驱动程序创建的线程?即使有多个处理线程,这也能工作吗?
I am writing a simple multi-threaded buffer. It's purpose is to hold data from the sound card until I can process them. It is implemented as a simple linked list (Element = list element, DataQueue = actual buffer, 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: %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;
}
The usage pattern is like this:
The audio driver (ASIO) is using callback functions to notify me when its buffers are ready for processing. This happens A LOT (dozen times per second). But I need to process the data only once per 5 seconds or so. So I use my own buffer to store 5 secs worth of sound data. Driver creates its own thread and executes the callback function. From this thread, I call append() and append the data from device buffers to my buffer. When the actual processing thread comes along, it cuts the buffer by getting the first element and reseting the buffer to 0 elements.
The problem is thread synchronization. The cut() and access() functions are mutually exclusive. I have Event HANDLE and I wait on this Event. I have some experience with Java, and am totally new to these Win32 APIs. Am I doing it right? Just like this, the program crashes on WaitForSingleObject, probably because I don't have SYNCHRONIZATION access right (c0000005). How can I set it to a thread created by a driver? Will this work even when there are multiple processing threads?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
EnterCriticalSection 成功了。
EnterCriticalSection did the trick.