gpt4 book ai didi

c++ - 如何让 Windows 线程同时处理两个函数?

转载 作者:行者123 更新时间:2023-11-28 00:40:55 25 4
gpt4 key购买 nike

问题很简单,但我找不到解决方案。我想调用两个函数并让它们同时运行(在不同的线程中),但我只能调用 void function1()void function2() 仅在之后运行,而不是在运行期间运行。我为处理器 1 和 2 设置了线程关联(我有一个多核处理器,希望你也有一个)。

我看到一次只调用一个函数的方式仅仅是因为我只得到了 function 1 的输出,而通常我会看到 function 1 的混合> 和 函数 2

请随意重新排列代码以使其尽可能工作,但请尽量保持原始方法的完整性,即类中线程调用函数的方式。这是完整的代码。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <iostream>

class thread_class
{
private:


public:

void function1()
{
for(int count = 0; count < 1000; count++)
std::cout<<"function 1"<<std::endl;
}
void function2()
{
for(int count = 0; count < 1000; count++)
std::cout<<"function 2"<<std::endl;
}
thread_class(){}
~thread_class(){}
DWORD_PTR WINAPI threadMain0()
{
function1();

return 0;
}
DWORD_PTR WINAPI threadMain1()
{
function2();

return 0;
}
void thread()
{
HANDLE *m_threads = NULL;
DWORD_PTR c = 2;

m_threads = new HANDLE[c];

DWORD_PTR i = 0;
DWORD_PTR m_id0 = 0;
DWORD_PTR m_mask0 = 1 << i;

m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain0(), (LPVOID)i, NULL, &m_id0);
SetThreadAffinityMask(m_threads[i], m_mask0);

wprintf(L"Creating Thread %d (0x%08x) Assigning to CPU 0x%08x\r\n", i, (LONG_PTR)m_threads[i], m_mask0);

i = 1;
DWORD_PTR m_id1 = 0;
DWORD_PTR m_mask1 = 1 << i;

m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain1(), (LPVOID)i, NULL, &m_id1);
SetThreadAffinityMask(m_threads[i], m_mask1);

wprintf(L"Creating Thread %d (0x%08x) Assigning to CPU 0x%08x\r\n", i, (LONG_PTR)m_threads[i], m_mask1);
}
};
int main()
{
thread_class* MAIN_THREADS;

MAIN_THREADS = new thread_class();

MAIN_THREADS->thread();

delete MAIN_THREADS;

return 0;
}

编辑:这是对以下代码稍作修改的版本,表明它不是并行运行的。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <iostream>

class thread_class
{
private:


public:

void function1()
{
int exit = 0;

while(exit == 0)
{
std::cout<<"enter 1 to exit:"<<std::endl;
std::cin>>exit;
};
}
void function2()
{
for(int count = 0; count < 1000; count++)
std::cout<<"function 2"<<std::endl;
}
thread_class(){}
~thread_class(){}
DWORD_PTR WINAPI threadMain0()
{
function1();

return 0;
}
DWORD_PTR WINAPI threadMain1()
{
function2();

return 0;
}
void thread()
{
HANDLE *m_threads = NULL;
DWORD_PTR c = 2;

m_threads = new HANDLE[c];

DWORD_PTR i = 0;
DWORD_PTR m_id0 = 0;
DWORD_PTR m_mask0 = 1 << i;

m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain0(), (LPVOID)i, NULL, &m_id0);
SetThreadAffinityMask(m_threads[i], m_mask0);

wprintf(L"Creating Thread %d (0x%08x) Assigning to CPU 0x%08x\r\n", i, (LONG_PTR)m_threads[i], m_mask0);

i = 1;
DWORD_PTR m_id1 = 0;
DWORD_PTR m_mask1 = 1 << i;

m_threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMain1(), (LPVOID)i, NULL, &m_id1);
SetThreadAffinityMask(m_threads[i], m_mask1);

wprintf(L"Creating Thread %d (0x%08x) Assigning to CPU 0x%08x\r\n", i, (LONG_PTR)m_threads[i], m_mask1);
}
};
int main()
{
thread_class* MAIN_THREADS;

MAIN_THREADS = new thread_class();

MAIN_THREADS->thread();

delete MAIN_THREADS;

return 0;
}

最佳答案

所以,有几件事:

1) 不能将常规成员函数用作 ThreadProc。如果你必须转换它才能编译它可能是错误的。 ThreadProc 函数需要是自由的或静态的。它们的签名也有误,因为 ThreadProc 采用单个 void* 参数。

2) 当您真正需要 DWORD 时,有几个地方可以使用 DWORD_PTR,例如 ThreadProc 的返回值、ci 等。

3) 来自 CreateProcess 文档:

调用 C 运行时库 (CRT) 的可执行文件中的线程应该使用 _beginthreadex 和 _endthreadex 函数进行线程管理,而不是 CreateThread 和 ExitThread;这需要使用 CRT 的多线程版本。如果使用 CreateThread 创建的线程调用 CRT,CRT 可能会在内存不足的情况下终止进程。

很有可能写入 cout 最终会命中 CRT。它可能不会,即使有,您也可能没有问题,但如果您有问题,那是一个值得关注的地方。

4) I/O 根本不能保证交错,所以写入 cout 不是决定线程是否同时运行的好方法。我已经添加了一些对线程的 Sleep 调用,并首先将它们创建为暂停状态,这样我就可以尽可能靠近地启动它们,使 I/O 看起来像是交错的,但这可能只是是巧合。一旦我确实看到你也可能是,当线程启动时,打印的字符串和 endl 没有相互连接,也就是说我看到两个字符串后跟两个行结束.之后有点交错。

5) 在从线程下删除类之前,您总是希望等待线程退出。您通常还希望在它们完成后关闭它们的句柄。

我删除了构造函数/析构函数,因为它们是空的,其他的只是为了尽可能简短。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <iostream>

class thread_class
{
public:
void function1()
{
Sleep(0);
for(int count = 0; count < 10; count++)
{
std::cout<<"function 1"<<std::endl;
Sleep(0);
}
}
void function2()
{
Sleep(0);
for(int count = 0; count < 10; count++)
{
std::cout<<"function 2"<<std::endl;
Sleep(0);
}
}
static DWORD WINAPI threadMain0(LPVOID param)
{
thread_class* This = static_cast<thread_class*>(param);
This->function1();
return 0;
}
static DWORD WINAPI threadMain1(LPVOID param)
{
thread_class* This = static_cast<thread_class*>(param);
This->function2();
return 0;
}
void thread()
{
HANDLE m_threads[2] = {};
DWORD threadIDs[2] = {};
LPTHREAD_START_ROUTINE threadProcs[2] = {threadMain0, threadMain1};
DWORD_PTR mask = 0;
for(int i = 0; i < 2; ++i)
{
m_threads[i] = CreateThread(NULL, 0, threadProcs[i], this, CREATE_SUSPENDED, &threadIDs[i]);
mask = 1 << i;
SetThreadAffinityMask(m_threads[i], mask);
wprintf(L"Creating Thread %d (0x%08p) Assigning to CPU 0x%08p\r\n", i, m_threads[i], mask);
}
for(int i = 0; i < 2; ++i)
{
ResumeThread(m_threads[i]);
}
WaitForMultipleObjects(2, m_threads, TRUE, INFINITE);
for(int i = 0; i < 2; ++i)
{
CloseHandle(m_threads[i]);
}
}
};

int main()
{
thread_class* MAIN_THREADS;
MAIN_THREADS = new thread_class();
MAIN_THREADS->thread();
delete MAIN_THREADS;
return 0;
}

关于c++ - 如何让 Windows 线程同时处理两个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18932011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com