我想将int变量传递给线程。
我的线程代码:
void record_WAVthread(void* data)
{
int channelId = *(int*)data;
cout<< "\n THREAD CREATED " << channelId;
(...)
_endthread();
}
我的线程创建代码:
extern HANDLE thread_audio_recording[MAX_INPUTS];
extern void record_WAVthread(void* data);
(...)
case 's':
if (!flag_recordingAudio)
{
//start recording
audioRecManager.isRecording = flag_recordingAudio = true;
for (int i = 0; i < 16; i++)
{
thread_audio_recording[i] = (HANDLE)_beginthread(record_WAVthread, 0, &i);
}
}
break;
输出:
THREAD CREATED 0
THREAD CREATED 5
THREAD CREATED 5
THREAD CREATED 9
THREAD CREATED 14
THREAD CREATED 15
THREAD CREATED 12
THREAD CREATED 11
THREAD CREATED 9
THREAD CREATED 12
THREAD CREATED 8
THREAD CREATED 7
THREAD CREATED 4
THREAD CREATED 2
THREAD CREATED 3
THREAD CREATED 6
我做错了什么?我应该得到1-16。
答案 0 :(得分:2)
您正在使用堆栈变量的地址作为参数的线程函数,这是Windows多线程编程中的常见错误。
&i
指向临时堆栈变量,该变量无法将其值保持在其范围之外。案件结束后可能是任何价值。您需要使用堆变量作为线程函数的参数。
但是对于您的代码,这里特别是一个简单的解决方案。
case 's':
if (!flag_recordingAudio)
{
//start recording
audioRecManager.isRecording = flag_recordingAudio = true;
for (int i = 0; i < 16; i++)
{
thread_audio_recording[i] = (HANDLE)_beginthread(record_WAVthread, 0, (void*)i);
}
}
break;
void record_WAVthread(void* data)
{
int channelId = (int)data;
cout<< "\n THREAD CREATED " << channelId;
(...)
_endthread();
}
答案 1 :(得分:0)
您正在向“i”传递指针,其值不断变化。当它启动第一个线程时,'i'可能已经(并且,从你的输出判断,它已经通过第二个线程创建)改变了,你的线程将不会产生你期望的输出。
如果要正确执行此操作,请创建一个大小为16的int数组,用0,1,2,..填充它,并将指针传递给由'i'索引的数组元素(即&amp; arr [i ])
另一个解决方案是欺骗编译器而不传递指针,但传递'i'本身,转换为void指针。当然,在线程中你不会取消引用它,而只是将其强制转换为int。
答案 2 :(得分:0)
您需要在线程回调函数中使用互斥锁。
std::mutex g_mutex;
void record_WAVthread(void* data)
{
g_mutex.lock();
int channelId = *(int*)data;
cout<< "\n THREAD CREATED " << channelId;
g_mutex.unlock();
(...)
_endthread();
}