2010-04-03 3 views
5

레거시 응용 프로그램과 함께 사용하기 위해 ADO/ODBC를 사용하여 데이터베이스 액세스를위한 다중 스레드 DLL을 작성했습니다. 각 스레드마다 여러 개의 데이터베이스 연결을 유지해야하므로 객체의 각 연결에 대한 ADO 객체를 배치하고 사용자 정의 threadInfo 객체 내부에 배열을 유지하려고합니다. 분명히 여기서 벡터가 더 잘 작동 할 것입니다. 이동 중에도 오브젝트를 삭제/재배치해야하며 벡터는이를 단순화 할 것입니다. 문제는 각 스레드에 힙을 할당하여 힙 경합을 피하고 거기에서 모든 메모리를 할당하는 것입니다.메모리 풀을 사용하는 클래스에서 C++ 벡터를 멤버로 사용

그럼 내 질문은 : 벡터를 스레드 별 힙에서 할당하도록하려면 어떻게해야합니까? (또는 래퍼 클래스와 같은 힙에서 메모리를 할당한다는 것은 내부적으로 알 수 있습니다. 소리는 거의 발생하지 않지만 C++ 사람이 아닙니다.) 저는 조금 봤는데 할당 자나 무언가를 써야 할 것처럼 보입니다. 내가 원치 않는 일들이 너무 많아 보인다. 다른 방법이 있습니까? 나는 벡터 내부에있는 모든 것들을 위해 새로운 배치를 사용한다고 들었습니다. 그래서 연산자 new에 과부하가 걸릴 수 있습니까?

C++의 내면에 대한 지식이 부족하여 필자가 주로 C 프로그래머 (심지어 상대적으로) 인 것처럼 보입니다. 어딘가 초보적인 것을 놓칠 수있는 가능성이 아주 있습니다. 더 쉬운 일이 생기지 않는다면, 나는 그 배열의 일을 그냥 할 수도 있지만, 그 일은 일어나지 않을 것입니다.

저는 MS-VC++ 6.0을 사용하고 있습니다. (헤이, 웃기 싫어! :-P).

모든/모든 도움을 많이 주시면 감사하겠습니다.

답변

3

어떻게하면 스레드 별 힙에서 벡터를 할당합니까?

적절한 할당자를 (컴파일 타임에) 전달합니다. Here 이렇게하는 방법에 대한 고전입니다. 그 기사의 조언을 따르거나 (심지어 코드를 복사하고 필요에 따라 수정하는 경우), 할당자를 작성하는 C 프로그래머는 동적으로 할당 된 배열을 사용하는 클래스의 복사 의미를 얻는 것보다 쉽습니다.

힙 (예 : 문자열)을 사용하는 벡터 (또는 자신의 배열, FTM)에 개체를 놓는 경우 특수 힙을 사용해야한다는 점에 유의해야합니다. 표준 라이브러리의 컨테이너 (std::basic_string<>은 컨테이너 임)의 경우 할당자를 전달할 수 있기 때문에 쉽습니다. 자신의 유형에 대해 반드시 자신을 만들어야합니다.

가능한 한 빨리 VC6에서 벗어나려고하십시오. 유독 하네.

+0

예, 전에이 문제를 겪었습니다. 솔직히 그들은 "새로운 코드를 오버로드하기 위해 이것을 사용하지 마십시오. 정상적인 코드에서 할당자를 사용할 이유가 없습니다." 다시 한번 확인해보십시오. 벡터의 개체는 특정 힙을 사용합니다. 예. 나는 이미 그것을 확신했다. basic_string의 템플릿에 대해 몰랐습니다. 감사합니다! (벡터를 제외하고는 모든 멤버를 프리미티브로 유지하는 데주의를 기울였습니다.) 한편 다른 응답이 나타나는지 기다리는 중! –

+0

@ Deep-B : 특수 힙에 객체를 놓아야한다는 것이 더 이상 "정상적인 코드"로 간주되지 않으므로 귀하의 경우에는 아무런 논점이 없습니다. ':)'C++의 문자열의 경우 : 표준 라이브러리의 ''헤더의'typedef basic_string string' (namspace'std' 또는 course 내)이 있습니다. 'std :: basic_string'에는 기본값이'std :: char_traits '과'std :: allocator ' 두 개의 템플릿 매개 변수가 더 있습니다. 'typedef std :: basic_string , my_allocator > my_string_type'이라면 자신 만의 힙을 사용하면서'std :: string'과 비슷한 것을 얻을 수 있습니다. – sbi

0

__declspec

다음 코드는 정수 스레드 로컬 변수를 선언하고 값으로 초기화 찾기 : 또 다른 노트에

__declspec(thread) int tls_i = 1; 

. 오랜 시간 동안 ADO 연결을 유지하는 것은 좋지 않습니다. db 연결에 많은 문제가 발생할 것입니다. 그들은 응용 프로그램에 공개됩니다. 그러나 쿼리를 보낼 때 "일반 네트워크 오류"메시지가 표시되어 폭탄을 터뜨릴 수 있습니다.

앱을 통해 가능한 한 빨리 연결을 닫고 OS에서 관리하는 연결 풀에 의존하는 것이 좋습니다.

또한 db에 연결하는 클라이언트 수에 따라 서버 쪽에서 열린 최대 소켓 수를 초과 할 수 있습니다. 이것은 메모리에 있습니다.클라이언트 측에서 연결이 닫히면 서버의 연결은 TIME_WAIT 상태가됩니다. 기본적으로 서버 소켓은 닫는 데 약 4 분이 걸리므로이 시간 동안 다른 클라이언트에서는 사용할 수 없습니다. 결론은 서버에 사용할 수있는 소켓 수가 제한되어 있다는 것입니다. 너무 많은 연결을 열어두면 문제가 발생할 수 있습니다.

죄송합니다. 주제를 벗어났습니다.

+0

죄송합니다, 사용할 수 없습니다 - __declspec is : 1> Vista 이전의 운영체제가 고장났습니다. (Vista는 실제로 무엇인가를 고정 시켰습니까? !!!!); LoadLibrary()를 통해 dll 함수를 호출하면 2> 실패합니다 (UB, 내 생각). 나는 이미 이것에 대한 연구를 한 후에 TLS 인덱스를 사용하기로 결정했다. ... 그리고 나는이 대답이 어떻게 관련되어 있는지 모르겠다. 나는 물건에 대해서 이야기하고있는 것을보고있다. 그러나 어쨌든 감사한다. –

+0

죄송합니다, 나는 __declspec (스레드)가 아닌 __declspec을 의미합니다. 명백하게. : P –

+0

흠, 불행히도 (연결 수명)이 내 손안에 없습니다. dll은 레거시 앱에 데이터베이스에 대한 쿼리를 실행하는 인터페이스를 제공하므로 다른 방법으로는 연결할 수 없습니다. 사용 FAQ에 당신의 조언을 넣을 수도 있습니다 - 실제로 호출자 프로그램을 코딩하려고하는 사람들에게. 타이밍 문제에 대한 정보를 제공해 주셔서 감사합니다. 더 많은 연구를해야 할 것 같아요. 일단 완료되면 DLL을 테스트하는 것뿐입니다 ... –

관련 문제