我正在使用Visual c ++学习多线程程序来开发声音信号处理程序。为了创建程序的基本结构,我编写了一个简单的代码,它有四个同步移动的线程,但它们不能正常工作。 规格如下。
该计划如下:
#include "process.h"
#include "windows.h"
#include "stdio.h"
class Sub_class
{
public:
HANDLE hEvent2;
Sub_class(int no);
bool loop_ok;
bool calcstart;
int sub_class_no;
void do_sub_loop2();
};
class Main_class {
public:
bool thread_go;
bool go_flag = false;
Sub_class *sub_cls[2];
Main_class();
~Main_class();
int start_loop();
};
Main_class *main_cls = 0;
HANDLE g_bg_wait = 0;
HANDLE g_main_event = 0;
bool bg_go = true;
unsigned __stdcall start_bg_loop(void *parg)
{
WaitForSingleObject(g_bg_wait, INFINITE);
while (bg_go)
{
Sleep(100); // goto sleep for 100 milliseconds
SetEvent(g_main_event);
}
return 0;
}
unsigned __stdcall start_main_loop(void *parg)
{
main_cls->start_loop();
return 0;
}
//---------------------------------------------------------------------------------
int main()
{
main_cls = new Main_class();
HANDLE hEvent = 0;
HANDLE hndl = 0;
hEvent = CreateEvent(NULL, TRUE, FALSE, "bg_event");
hndl = (HANDLE)_beginthreadex(0, 0, &start_bg_loop, 0, 0, 0);
g_bg_wait = hEvent;
hEvent = CreateEvent(NULL, FALSE, FALSE, "main_event");
hndl = (HANDLE)_beginthreadex(0, 0, &start_main_loop, 0, 0, 0);
g_main_event = hEvent;
main_cls->sub_cls[0] = new Sub_class(0);
main_cls->sub_cls[1] = new Sub_class(1);
Sleep(1000);
bg_go = false;
CloseHandle(g_bg_wait);
CloseHandle(g_main_event);
}
int Main_class::start_loop()
{
Sleep(10);
SetEvent(g_bg_wait);
while (thread_go)
{
WaitForSingleObject(g_main_event, INFINITE);
printf("Trigger SubClass 0\n");
sub_cls[0]->calcstart = true;
SetEvent(sub_cls[0]->hEvent2);
if (go_flag)
{
printf("Trigger SubClass 1\n");
sub_cls[1]->calcstart = true;
SetEvent(sub_cls[1]->hEvent2);
}
else
{
sub_cls[1]->calcstart = false;
}
go_flag = !go_flag;
}
return 0;
}
Main_class::Main_class()
{
thread_go = true;
}
Main_class::~Main_class()
{
thread_go = false;
}
static unsigned __stdcall executeLauncher2(void* args) {
reinterpret_cast<Sub_class*>(args)->do_sub_loop2();
return 0;
}
Sub_class::Sub_class(int no)
{
sub_class_no = no;
loop_ok = true;
hEvent2 = CreateEvent(0, FALSE, FALSE, "event_2");
_beginthreadex(0, 0, &executeLauncher2, (void *)this, 0, 0);
}
void Sub_class::do_sub_loop2()
{
while (loop_ok)
{
WaitForSingleObject(hEvent2, INFINITE);
if (calcstart) printf("Start SubClass %d : OK\n", sub_class_no);
else printf("Start SubClass %d : NG ---\n", sub_class_no);
}
}
运行该程序的结果如下:
Trigger SubClass 0
Start SubClass 0 : OK
Trigger SubClass 0
Trigger SubClass 1
Start SubClass 1 : NG ---
Start SubClass 0 : OK
Trigger SubClass 0
Start SubClass 1 : NG ---
Trigger SubClass 0
Trigger SubClass 1
Start SubClass 0 : OK
Start SubClass 1 : OK
Trigger SubClass 0
Start SubClass 0 : OK
Trigger SubClass 0
Trigger SubClass 1
Start SubClass 1 : NG ---
Start SubClass 0 : OK
Trigger SubClass 0
Start SubClass 1 : NG ---
Trigger SubClass 0
Trigger SubClass 1
Start SubClass 1 : OK
Start SubClass 0 : OK
Trigger SubClass 0
Start SubClass 1 : NG ---
从结果中可以看出,即使触发sub_thread [0],也经常调用sub_thread [1](NG行)。 我想创建程序,以便在触发sub_thread [0]时调用sub_thread [0]并在触发sub_thread [1]时, 调用sub_thread [1],也就是说,我想阻止NG行。
你能教我如何解决这个问题吗? 提前谢谢。
答案 0 :(得分:5)
CreateEvent(0, FALSE, FALSE, "event_2");
在此创建或打开相同的事件,因为您将名称传递给该函数。甚至程序的多个实例也会打开相同的事件对象。如果任何其他程序创建了一个具有通用名称“event_2”的事件,您也可以打开它。那肯定不是你想要的。
传递NULL
作为最后一个参数,为每个线程创建不同的事件对象。命名事件通常仅用于跨进程同步(在这种情况下,使用唯一的名称,如GUID),这里不需要。