클래스 멤버 함수에서 트레드를 만들고 클래스 생성자 초기화 프로그램 목록을 통해 스레드를 초기화하려고합니다.스레딩 클래스 멤버 함수; 초기화 도구 목록을 통한 스레드 초기화
Receive_List.push_back(CurVal++)
에 대한 호출 중에 스레드 예외 실행이 발생하지만이 예외는 기능의 첫 번째 명령으로 printf()
을 단순히 놓으면 피할 수 있습니다.
#include <thread>
#include <list>
class SomeClass
{
std::thread Receive_Thread;
std::list<unsigned int> Receive_List;
void Receive_Main()
{
//printf("Hacky Way Of Avoiding The Exception\n");
const unsigned int MaxVal = 3000;
unsigned int CurVal = 0;
while (CurVal < MaxVal)
{
Receive_List.push_back(CurVal++);
}
}
public:
SomeClass() :
Receive_Thread(std::thread(&SomeClass::Receive_Main, this))
{}
~SomeClass()
{
Receive_Thread.join();
}
void ProcessReceiveList()
{
if (!Receive_List.empty())
{
printf("Received Val: %i\n", Receive_List.front());
Receive_List.pop_front();
}
}
bool IsReceiveEmpty()
{
return Receive_List.empty();
}
};
int main()
{
SomeClass* MyObject = new SomeClass();
//
// Sleep for 1 second to let the thread start populating the list
std::this_thread::sleep_for(std::chrono::seconds(1));
while (!MyObject->IsReceiveEmpty())
{
MyObject->ProcessReceiveList();
}
delete MyObject;
std::system("PAUSE");
return 0;
}
왜 이런 일이 발생합니까?
왜'printf()'를 주석 해제하면 예외없이 코드를 실행할 수 있습니다. 나는 단순히 list :: push와 list :: pop 함수를 사용하는 것이 문제없이 동시에 실행될 수 있다는 인상을 받았다. 또한 주 스레드의 while 루프를'while (true) {}'로 바꾸면 여전히 예외가 발생합니다. – KKlouzal
@KKlouzal : 정의되지 않은 동작은 종종 의미가 없습니다. 표준 컨테이너는 동기화되지 않습니다. 너 자신을 돌봐 줘야 해. 참으로 또 다른 문제가 있는데, 나는이 질문에 답을 추가 할 것입니다. –
모든 정보를 제공해 주셔서 감사합니다. 클래스 정의에서 변수를 선언 한 순서가 초기화 된 순서를 나타냈다는 것을 알지 못했습니다. – KKlouzal