STL 을 사용한 코드가 자꾸 죽습니다. ㅡ.ㅜ

kuaaan의 이미지

bool	popFromTheMap(struct TimedJob& resultJob)
{
	memset(&resultJob, NULL, sizeof(struct TimedJob));

	multimap <CTimeStamp, struct TimedJob, ltTimeStamp>::iterator cur;

	CEnterCriticalSection Crit(&crit_TimedJob_Map);

	cur = TimedJob_Map.begin();

	if (cur != TimedJob_Map.end && cur->second.execTime.isExpired()){
 			resultJob = cur->second;
			TimedJob_Map.erase(cur);   // 여기서 죽습니다.
			return true;
	} 

	return false;
}

VisualC++ 6.0 + stlPort 입니다.

위와 같은 코드를 짰는데요...
TimedJob_Map.erase(cur); 이부분에서 자꾸 죽습니다. (간헐적으로 ..)
CEnterCriticalSection이란 건 제가 만든 클래스인데요... 생성자에서 인자로 주어진 CriticalSection개체에 Lock을 걸고
소멸자에서 Unlock을 합니다. 그외의 execTime 등은 다 제가 만든 클래스입니다.

현재 의심되는건 쓰레드 동기화 문제와 STL 문법에 관한 문제인데요...
혹시 제가 STL 문법을 잘못 썻나요? 위의 구문에서 cur = TimedJob_Map.begin(); 이부분이 실패할경우
(원소가 하나도 들어있지 않은 경우겠지요?)가 위의 코드로 제대로 걸러지는지요?

답답해죽겠습니다. 내일까지 해결해내라는데... ㅡ.ㅜ
납기의 압박은 심해지고... 흑흑...

kuaaan의 이미지

아참... 죽는 원인은 'Access Violation'이라네요.
Linux식으로 말하면 'Segmentation Fault'겠지요?

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

자룡의 이미지

올려주신 코드상에선 TimedJob_Map 에 어떤 값을 넣는 부분이 없어서 그렇지만..
일단 begin() 은 원소가 없으면 end() 와 같은 값을 갖게되니
if 문에는 문제가 없어 보입니다.

Access Violation 이라는 말 자체로 보면
다른 스레드에서 컨테이너에 어떤 입력 작업등을 해버려서
반복자를 무효화 시켜버린게 아닌가 의심이 되네요.

CEnterCriticalSection 소스가 없어서 그런데
여기에서 락을 제대로 못거는게 아닌지 확인이 필요할듯 합니다.

-----
이글을 읽는 모든 이에게 평화가 함께 하기를... ^^;

-----
이글을 읽는 모든 이에게 평화가 함께 하기를... ^^;

오장현의 이미지

혹시 최적화(Optimization)옵션이 선택되어있으면 그 선택을 끄고 다시 한 번 해 보세요.

(그리고, if 문 안에서 TimedJob_Map.end 로 타이핑 하신 건 아니죠? TimedJob_Map.end() 를 잘못 쓰신 거겠죠?)

kuaaan의 이미지

Quote:

혹시 최적화(Optimization)옵션이 선택되어있으면 그 선택을 끄고 다시 한 번 해 보세요.

(그리고, if 문 안에서 TimedJob_Map.end 로 타이핑 하신 건 아니죠? TimedJob_Map.end() 를 잘못 쓰신 거겠죠?)

아.. 물론이죠. 오타에요. 오타. ^^

안그래도... 지금 CEnterCriticalSection을 다 빼고 원시적인 코드로 바꾸는 작업을 하고 있습니다.

바꾸니까 안죽는것 같기도 하고.. ^^;;

나중에 이 CEnterCriticalSection 코드를 한번 올려보겠습니다.
도대체 뭐가 잘못된 건지.. 도저히 제가보기엔 멋지기만 하구마. ^^;;

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

kuaaan의 이미지

내친김에 올려봅니다.

class CEnterCriticalSection
{
// Critical Section 을 lock 하고 unlock하는데 쓰이는 클래스. 
// 선언된 함수에서 빠져나갈때 자동으로 지정된 critical section을 unlock한다.
private:
	LPCRITICAL_SECTION m_pCriticalSection;

public:
	CEnterCriticalSection()	// 사용될 일 없다.
	{
		this->m_pCriticalSection = NULL;
	}

	CEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
	{
		this->m_pCriticalSection = lpCriticalSection;
		EnterCriticalSection(lpCriticalSection);
	}

	CEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection, bool blLock)
	{
		this->m_pCriticalSection = lpCriticalSection;
		if (blLock)
			EnterCriticalSection(lpCriticalSection);
	}

	~CEnterCriticalSection()
	{
		if (this->m_pCriticalSection)
			LeaveCriticalSection(this->m_pCriticalSection);
	}


};

도대체 어디가...? ^^;
----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

오장현의 이미지

Quote:
CEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection, bool blLock)
{
this->m_pCriticalSection = lpCriticalSection;
if (blLock)
EnterCriticalSection(lpCriticalSection);
}

이게 문제가 될지는 모르겠습니다만...

코드의 다른 부분에서 blLock 을 false 로 해서 생성시키는 경우가 있나요?

그런 경우에 EnterCriticalSection은 호출된 적도 없는데 소멸자에서 LeaveCriticalSection을 호출하겠군요.

--

그리고, 앞서 최적화 옵션을 말씀드렸는데요.

며칠전에 (제가 보기엔 아무런 문제가 없는) 프로그램에 계속 에러가 발생해서

MinGW로 컴파일해서 실행시켜보니 잘 되었던 경우가 있습니다.

그래서 혹시 싶어서 VS .Net 2003의 프로젝트 속성에서 최적화 옵션을 끄니까 그때서야 MinGW에서 처럼 잘 되더라구요. -_-;;;;;

kewlbear의 이미지

위에 보여주신 코드에는 InitializeCriticalSection이 없어서 혹시 CriticalSection 자체가 제대로 초기화 되지 않았는지 궁금합니다. 그리고 사용될 일이 없는 생성자라면 아예 빼버리는 것이 낫겠네요. 참고로 제가 사용하는 클래스는 아래와 같습니다.

template<class T> class Lock {
public:
    Lock(T& object) : object_(object) { object_.acquire(); }
    ~Lock() { object_.release(); }
private:
    T& object_;
}; // class Lock
 
class CriticalSection {
public:
    CriticalSection() { InitializeCriticalSection(&criticalSection_); }
    ~CriticalSection() { DeleteCriticalSection(&criticalSection_); }
    void acquire() { EnterCriticalSection(&criticalSection_); }
    void release() { LeaveCriticalSection(&criticalSection_); }
private:
    CRITICAL_SECTION criticalSection_;
}; // class CriticalSection

아래와 같이 씁니다.
CriticalSection criticalSection;
// ...
Lock<CriticalSection> lock(criticalSection);
// 동기화가 필요한 작업

kuaaan의 이미지

아.. 위에분이 지적해주신 파라메터 두개짜리 생성자는
만들어놓기만 하고 쓰진 않습니다. 지우고 올린다고 하는게 깜빡했네요.
lock, unlock하는 코드가 있었는데... 사용안해서 지우고 올렸지요. 함께 지워야 하는데 깜빡했습니다.

초기화는 합니다. ^^;

음.. 올려주신 코드가 Wrapping을 한번 더 해서 초기화하는 부분까지 커버하는 것만 빼고는 차이가 없어보이는데요... ^^;
왜 내새끼는 이렇게 비리비리한지... ㅜ.ㅜ

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

lovewar의 이미지

if (cur != TimedJob_Map.end && cur->second.execTime.isExpired()) {
 			resultJob = cur->second;
			TimedJob_Map.erase(cur);   // 여기서 죽습니다.
			return true;
} 

간혹, iterator를 직접 조작할때 이런 문제가 있다고 하던데요(무책임한 발언).
그래서 다음과 같이 변경해 봤습니다.
if (cur != TimedJob_Map.end) {
    resultJob = (*cur).second;
    if (resultJob.execTime.isExpired()) {
        TimedJob_Map.erase(cur);   // 여기서 죽습니다.
        return true;
    } else {
       /* memset(&resultJob, NULL, sizeof(struct TimedJob)); */
    }
} 

궁금하군요. 원인이 뭔지...

kuaaan의 이미지

아아... 정말 오랜만에 들어왔습니다.. ^^

이 글을 올린 게 딱 일년정도 되었네요. 그사이에 전 플젝 잘 끝내고, 결혼도 하고.. 바뀐게 많았답니다. ^^
지금보니 정말 많은 분들이 함께 고민해주셨네요...
이런 게 프로그래밍하는 맛인것 같습니다. ^^

이거 보고 생각나서 올리는 건데요... 저 문제는... STL 과는 아무 상관없는 다른 문제로 밝혀졌습니다.

모냐하면... Windows의 비동기 IO모델중에 CALLBACK함수를 사용한 Overlapped 모델이란 게 있지요..
거기서 비동기 IO함수를 호출하면서 Overlapped구조체를 넘겨줄때 이걸 동적할당해야 하는데
로컬변수를 사용해서.. CALLBACK이 되었을때 그 메모리가 무효화된 상태가 되어버리는게 문제였습니다.

그런데.. 멀티쓰레드에서 꼬이다 보니 엉뚱한데 문제가 있는 것처럼 보였던 거죠.

지금같으면.. 후배가 그런코드를 짜놓으면 기초가 부실하다고 쿠사리 주었겠지만... ㅎㅎ
그때는 비동기IO가 뭔지도 잘 모르면서 무턱대고 코드를 짜다 보니 그랬답니다.
아.. 그때는 정말 피가 바짝바짝 말랐더랩니다. ㅎㅎ

전 요즘 프로그래밍이 재미가 없어졌어요.

여러분들은 어떠신가요?? ㅡ.ㅜ

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.