2009-11-23 4 views
0

새로운 스레드를 만드는 방법을 배우고 실행하려고합니다. 새 스레드에서 실행되는 함수에 몇 가지 변수를 전달해야하지만 실제로 새 함수/스레드에 아무 것도 전달하는 방법을 찾을 수 없습니다.새 스레드에 여러 힙 배열을 전달하는 방법은 무엇입니까?

나는 http://www.devarticles.com/c/a/Cplusplus/Multithreading-in-C/1/을 따르고 있지만 하나의 매개 변수 만 전달하는 방법과 다른 방법은 다루지 않습니다.

질문과 대답은 다른 스레드를 제외하고는 함수가하는 것과 똑같은 방식으로 작동합니까 아니면 그냥 그보다 조금 더 복잡합니까?

감사합니다,

-Faken

답변

4

근본적인 OS 스레드 CreateThread 하나만 파라미터를 전달할 수

uintptr_t _beginthreadex( 
    void *security, 
    unsigned stack_size, 
    unsigned (*start_address)(void *), 
    void *arglist, 
    unsigned initflag, 
    unsigned *thrdaddr 
); 

이러한 제한 사항이 주어지면 일반적인 규약에서는 모든 인수가있는 구조/클래스에 대한 포인터를 전달합니다. =

class Foo 
{ 
    int _someState; 
    int _otherState; 
    char _moreState[256]; 

    unsigned DoWork(); 
    static unsigned ThreadHandler(void*); 

public: 
    void StartThread(); 
} 

void Foo::StartThread() 
{ 
    _beginthreadex(..., Foo::ThreadHandler, this, ...); 
} 

unsigned Foo::ThreadHandler(void* arglist) 
{ 
    Foo* pFoo = (Foo*) arglist; 
    return pFoo->DoWork(); 
} 

unsigned Foo::DoWork() 
{ 
    // do here all the thread work 
} 

이것은 매우 일반적인 관용구가 효과에 당신이 (많은 상태를 전달할 수 있습니다 : 보통, C++로, 하나의 스레드 핸들러됩니다 정적 함수를 만든 인수로 인스턴스를 전달합니다 인수)를 필요에 따라 스레드에 할당합니다.

2

하나의 매개 변수는 포인터의 크기를 가지고있다. 따라서 구조체를 원하는만큼 많이 채우고 새 구조체를 만들 때이 구조체에 대한 포인터를 전달할 수 있습니다. 큰 구조체를 함수에 전달할 때와 동일합니다.

스레드 실행에 대해서는 정확히 동일하지만 프로그램의 다른 스레드와 병렬로 실행됩니다. 따라서 다른 스레드가 동시에 액세스 할 수 있으므로 스레드의 전역 변수에 액세스 할 때주의를 기울여야합니다. 이름 arglist를 임에도 불구

HANDLE WINAPI CreateThread(
    __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, 
    __in  SIZE_T dwStackSize, 
    __in  LPTHREAD_START_ROUTINE lpStartAddress, 
    __in_opt LPVOID lpParameter, 
    __in  DWORD dwCreationFlags, 
    __out_opt LPDWORD lpThreadId 
); 

따라서 CRT 스레드 하나 개의 매개 변수도 허용 함수를 생성 :

+0

그렇다면 정규 함수처럼 몇 개의 배열을 새 스레드로 완전히 넘길 수 없다는 뜻입니까? 내 힙 배열에 대한 포인터를 포함 할 구조체에 포인터를 전달해야합니까? 더 쉬운 직접적인 방법이 있습니까? – Faken

+0

그것은 당신이해야 할 일과 거의 같습니다. 어쨌든 나사산 가공의 다른 악몽과 비교할 때 그다지 나쁘지 않습니다. ;) – Macke

+0

내가 생각할 수있는 더 쉬운 방법은 없다. (그러나 배열은 실제로 첫 번째 요소에 대한 포인터이므로 구조체를 복잡하게 만들지 않는다.) –

2

boost::thread 여러 매개 변수가있는 스레드를 만들 수 있습니다. Windows 스레드 API 대신 사용할 수 있습니다.

1

나는 Remus Rusanu의 답을 다시 한번 말하고 싶습니다. 단일 매개 변수를 전달하면 많은 사람들이 지적한 것처럼 임의의 데이터 크기를 전달할 수 있습니다. 포인터구조체에 전달하여 전달하려는 항목이 포함되어 있으면됩니다. 정말 간단합니다. Remus Rusanu의 C++ 스타일이긴하지만 제 제안은 다소 C 스타일입니다.

struct THREAD_DATA { 
    int data1; 
    struct MYSTRUCT data2; 
    ... 
}; 

void foo() 
{ 
    ... 
    // It's important not to pass a stack-allocated local structure. 
    // That can be invalidated when this function exits. 
    // So, safely allocated with malloc/new. 
    THREAD_DATA* data = new THREAD_DATA; 
    data->data1 = // put the value you want to pass 
    data->data2 = // 
    _beginthreadex(..., ThreadWorkerFunc, data, ...); 
} 


unsigned int CALLBACK ThreadWorkerFunc(void* arg) 
{ 
    THREAD_DATA* data = (THREAD_DATA*)arg; 
    ... = data->data1 


    delete data; 
    return 0; 
} 
관련 문제