thread class 컴파일 에러.

theone3의 이미지

아래는 코드입니다.

int CThread::Run(void)
{
    if(pthread_create(&mtid, NULL, &do_it, NULL) != 0)
    {
        cout << "pthread_create error" << endl;
    }
    return(0);
}
   
void* CThread::do_it(void* arg)
{
    while(1)
    {
        sleep(1);
        cout << "....." << endl;
    }
    return;
}

아래는 에러 메시지 입니다.

"CThread.cc", line 38: Error: Formal argument 3 of type extern "C" void*(*)(void*) in call to pthread_create(unsigned*, const _pthread_attr*, extern "C" void*(*)(void*), void*) is being passed void*(CThread::*)(void*).
"CThread.cc", line 52: Error: "CThread::do_it(void*)" is expected to return a value.
2 Error(s) detected.

위와 같은 예제를 C로 짜서 돌리면 잘 실행이 됩니다.
그런데, C++로는 컴파일 에러가 나는데,
어떻게 해야하는지 막막하네요,
도움을 주세요.

cinsk의 이미지

CThread::do_it()은 void *를 리턴하게 되어 있습니다. 위 함수를 보니 그냥 "return;"을 하셨네요.

theone3의 이미지

아. 두번째 에러는 중요한 게 아닙니다.
문제의 핵심은 첫번째 에러를 잡는 겁니다.

당신은 사랑받기 위해 태어난 사람.

cinsk의 이미지

한 가지더, member function에 대한 포인터를 직접 void *(*)(...)로 캐스팅할 수 없습니다. do_it()을 static member function으로 만드는 등의 작업이 필요합니다.

theone3의 이미지

int CThread::Run(void) 
{ 
    if(pthread_create(&mtid, NULL, &do_it, NULL) != 0) 
    { 
        cout << "pthread_create error" << endl; 
    } 
    return(0); 
} 
    
static void* CThread::do_it(void* arg) 
{ 
    while(1) 
    { 
        sleep(1); 
        cout << "....." << endl; 
    } 
    return; 
}

코드를 이렇게 바꾸고 나서 컴파일을 다시 했습니다.
CC(솔라리스)에서는 에러가 나고 g++은 컴파일이 됩니다.

CC에서의 에러는

Quote:
"CThread.cc", line 38: Error: Formal argument 3 of type extern "C" void*(*)(void*) in call to pthread_create(unsigned*, const _pthread_attr*, extern "C" void*(*)(void*), void*) is being passed void*(CThread::*)(void*).

입니다. 처음의 에러와 같은 상황인데요,
이 이유를 설명해 주시면 감사하겠습니다.

당신은 사랑받기 위해 태어난 사람.

chadr의 이미지

pthread_create(&mtid, NULL, &do_it, NULL) 가 아니라
pthread_create(&mtid, NULL, do_it, NULL) 가 되어야 할듯합니다.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

theone3의 이미지

chadr wrote:
pthread_create(&mtid, NULL, &do_it, NULL) 가 아니라
pthread_create(&mtid, NULL, do_it, NULL) 가 되어야 할듯합니다.

do_it은 function을 가리키게 되는데,
원래 function은 그 주소가 불려지기 때문에,
&가 있건 없건 상관없는 것으로 알고 있습니다.

그리고 &를 빼고 컴파일을 해도 똑같은 에러가 납니다.

답변 감사합니다.

당신은 사랑받기 위해 태어난 사람.

theone3의 이미지

dongyuri wrote:
int CThread::Run(void) 
{ 
    if(pthread_create(&mtid, NULL, &do_it, NULL) != 0) 
    { 
        cout << "pthread_create error" << endl; 
    } 
    return(0); 
} 
    
static void* CThread::do_it(void* arg) 
{ 
    while(1) 
    { 
        sleep(1); 
        cout << "....." << endl; 
    } 
    return; 
}

코드를 이렇게 바꾸고 나서 컴파일을 다시 했습니다.
CC(솔라리스)에서는 에러가 나고 g++은 컴파일이 됩니다.

CC에서의 에러는

Quote:
"CThread.cc", line 38: Error: Formal argument 3 of type extern "C" void*(*)(void*) in call to pthread_create(unsigned*, const _pthread_attr*, extern "C" void*(*)(void*), void*) is being passed void*(CThread::*)(void*).

입니다. 처음의 에러와 같은 상황인데요,
이 이유를 설명해 주시면 감사하겠습니다.

제가 하다가 글을 잘 못 올렸습니다.
static을 추가한 곳은 class의 정의가 아니라, 선언부입니다.
위의 코드는 static을 추가하지 않고 클래서 선언에서
static을 추가했습니다.

당신은 사랑받기 위해 태어난 사람.

익명 사용자의 이미지

CThread.h

#include <pthread.h>
#include <iostream>

using namespace std;

class CThread
{
    private :
        pthread_t   mtid;
        static pthread_mutex_t mutex_lock;
    public :
        CThread();
        ~CThread();
        pthread_t getTid();
        int Run(void);
        static void * do_it(void *);

};

CThread.cpp

#include "CThread.h"
#include <unistd.h>

CThread::CThread()
{

    pthread_mutex_init(&mutex_lock, NULL);
}


CThread::~CThread()
{

}


pthread_t CThread::getTid()
{
    return mtid;
}


int CThread::Run(void)
{
   
    if(pthread_create(&mtid, NULL, do_it, (void *)&mtid) != 0)
    {
        cout << "pthread_create error" << endl;
    }
    return(0);
}
   
void* CThread::do_it(void* arg)
{
    while(1)
    {
        sleep(1);
        pthread_mutex_lock(&mutex_lock);
        cout << *(unsigned int *)arg << "....." << endl;
        pthread_mutex_unlock(&mutex_lock);
    }
    return NULL;
}

main.cpp

#include "CThread.h"
#include <unistd.h>


int main(int argc, char * argv[])
{

    CThread a;
    CThread b;
    CThread c;

    a.Run();
    b.Run();
    c.Run();

    while(1)
    {
        sleep(1);
    }

}[quote]


코드가 그다지 길지 않으므로 전체를 다 올렸습니다.
CC(솔라리스 컴파일러)에서의 문제는 아직 해결이 되지 않았습니다.

제가 하려고 하는 것은 class가 호출 될때 thread가 하나씩 생성되는 것입니다.
그리고 이들의 동기화를 위해서
mutex_lock이란 변수를 쓰려고 합니다.
mutex_lock이란 변수는 static으로 선언을 했는데,
이것은 생성된 클래스에서 공통으로 쓰려고 합니다.
static의 목적이 그런 것으로 알고 있습니다.

CThread.cc는 컴파일이 되지만 링크에서 에러가 납니다.
제가 구현하려고 하는 코드가 개념상 잘못된 것인지,
에러의 원인이 무엇인지 같이 봐주시면 감사하겠습니다.[/quote]
theone3의 이미지

로그인이 풀려 버렸네요.
바로 위는 제가 올린 글입니다.

당신은 사랑받기 위해 태어난 사람.

익명 사용자의 이미지

if(pthread_create(&mtid, NULL, do_it, (void *)&mtid) != 0) 

대신

int status = 0;
status = pthread_create(&mtid, 0, do_it, this);
if(staus  != 0) 
익명 사용자의 이미지

추가적으로 Thread 클래스를 재사용할 수 있게끔 변경하세요.

견본은 Applied C++ 책에 Chapter 5를 참조하시기 바랍니다.

theone3의 이미지

위에 손님들 그리고 답변 해주신 분들 모두 감사합니다.

처음에 나온 Error는 Warning이 되었습니다. ( CC로 컴파일 할때)

지금 print.google.com에서 Applied C++을 읽어보고 있습니다.

읽어보고 구현하다가 문제가 더 있으면 또 질문 드리겠습니다.

당신은 사랑받기 위해 태어난 사람.

theone3의 이미지

뭐 이것 저것 하다보니, 시간이 많이 흘렀네요 ^^

제가 하고 싶은 일은 이런 겁니다.

int do_my_work()
{
	cout << "do my work...." << endl;
	return(0);
}

int main(int agrc, char * argv[])
{
	CThread a;
	a.run(do_my_work);
	a.end();

	return(0);

}

class CThread {
private :
	tid;
public :
	CThread();
	~CThread();
	run(void *);
	end();
	
};

CThread::run(void * t)
{
	pthread_create(&tid, 0, t, 0);
}
CThread::end(void)
{
	pthread_join(tid);
}


진행하면서 보니, 궁극적으로 제가 하려는 것이 가능한 것인지 의문이 듭니다.
그럼 제가 먼저 설명을 드릴테니, 이것이 가능한지 불가능한지 알려주세요.
위의 코드는 정확한 코드는 아니지만, 대략적인 pseudo코드입니다.
main에서 CThread 클래스를 생성해서, 함수를 run에 인자로 넘겨줍니다.
그러면 CThread 클래스 안에서 run함수가 넘겨받은 함수를 pthread create로
실행합니다.
그리고 CThread::end를 호출해서 이 thread가 종료하도록 기다립니다.

제가 가장 의심스러운 부분은 과연 class에 인자로 함수(혹은 함수 포인터)를
넘길 수 있는가 하는 것입니다. 즉.

a.run(do_my_work);

이 부분입니다. 물론 그외에도 해결해야할 문제는 많습니다. ㅠㅠ

그럼 많은 분들의 답변을 기다리겠습니다.
또 이런 형태의 프로그램을 짠다면 주의할 점도 지적해 주시면
감사하겠습니다.

당신은 사랑받기 위해 태어난 사람.

댓글 달기

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