cpp 인스턴스별 스레드 세이프티....?

메가삽질러의 이미지

멀티스레드 프로그램을 작성하는 중에 생각이 나서 만들어 봤습니다... 굳이 필요해서 보다는 그냥 떠올라서 써본것이구요 좋은점 나쁜점 들어보고 싶어서 올려봅니다.
틀린것 지적도 환영입니다. 윈도우에서 작동할 코드입니다.
ThreadSafe 클래스를 상속하는 모든 클래스들이 public으로 공개된 함수의 시작과 끝에
lock, unlock함수를 호출함으로써 같은 인스턴스에 대해 스레드 세이프티를 구현함과 동시에
같은 스레드에서의 재진입을 허용할 수 있을까 (단일 스레드에서의 데드락을 막아보려고...) 하는 생각에서 작성한 코드입니다.

class ThreadSafe
{
public:
	ThreadSafe():thread_safe_mutex_(CreateMutex(0,0,0)),thread_handle_(NULL){}
	~ThreadSafe(){CloseHandle(thread_safe_mutex_);}
protected:
	void lock(){
		bool iteration = true;
		while(iteration){
			WaitForSingleObject(thread_safe_mutex_,INFINITE);
			if(lock_count_==0){
				thread_handle_=GetCurrentThreadId();
				lock_count_++;
				iteration=false;
			}
			else if(thread_handle_==GetCurrentThreadId()){
				lock_count_++;
				iteration=false;
			}
			ReleaseMutex(thread_safe_mutex_);
		}
	};
	void unlock(){
		WaitForSingleObject(thread_safe_mutex_,INFINITE);
			lock_count_--;
		ReleaseMutex(thread_safe_mutex_);
	}
private:
	mutable HANDLE thread_safe_mutex_;
	unsigned int lock_count_;
	HANDLE thread_handle_;
};
 
 
class TestClass : public ThreadSafe
{
public:
	TestClass():_count(10){}
	~TestClass(){}
	int get_num();
	void set_num(int num);
	void recursive_count();
private:
	int _num;
	int _count;
};
 
int TestClass::get_num(){
	lock();
	int _num=num;
	unlock();
	return num;
}
 
void TestClass::set_num(int num){
	lock();
	_num=num;
	unlock();
}
 
void TestClass::recursive_count(){
	lock(); 
		printf("%d\n",_count );
		_count--;
		if(_count)
			recursive_count();
	unlock();
	return;
}
jick의 이미지

제가 대충 보기에는 성능에 문제가 있을 것 같습니다.

쓰레드 A가 락을 건 상태에서 다른 쓰레드 B가 lock()을 부르면 A가 끝날 때까지 B는 lock 함수 안에서 끊임없이 락을 풀었다 걸었다 하며 무한루프를 돌게 됩니다. 같은 리소스에 대해 조금만 경쟁이 생겨도 CPU에 상당한 부하가 걸릴 수 있습니다.

원하시는 동작을 하려면 condition variable을 찾아보시는 걸 추천합니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.