2009-04-20 5 views
0

MATLAB mex 함수에서 멀티 스레딩을 테스트하기 위해 약간의 코드가 있습니다. (MATLAB은 스레드로부터 안전하지 않습니다. 나는 무슨 일이 일어나는지보기 위해 놀고있다). MATLAB C 코드 함수의 진입 점에는 게시물의 맨 아래에있는 코드에서 mexFunction 함수의 서명이 있습니다. 기본적으로이 함수의 인수를 pthread를 사용하여 만든 다른 스레드로 전달하려고하므로 모든 것을 구조로 묶어야합니다. (변경할 수없는) mexFunction의 시그니처는 mxArray에 대한 포인터의 배열을 포함합니다. 그러나 mxArray에 대한 포인터의 배열을 구조체 정의에 직접 포함 할 수는 없으므로 구조체의 해당 필드에 할당 할 수 없습니다. 배열에 할당 할 수 없습니다). 예를 들어,이 작동하지 않습니다 내가 다른 스레드에서이 구조를 사용할 때 다음, 그러나const에 대한 포인터의 배열에서 const-cast를 던지거나 C에 관한 다른 질문

typedef struct MexFunArgs { 
    int nrhs; 
    const mxArray **prhs; 
} MexFunArgs; 

:

typedef struct MexFunArgs { 
    int nrhs; 
    const mxArray *prhs[]; 
} MexFunArgs; 

/* ... now within the mexFunction ... */ 

MexFunArgs mfa; 

mfa.prhs = prhs; 

이 문제를 해결하는 첫 번째 생각은 다음과 구조 정의를 변경하는 것입니다 , 내가 포인터가 배열 mexCallMATLAB 함수에 전달하는 배열로 다시 캐스팅해야 할 것입니다. 내가 아는 한 수행 할 수 없다는 것을 알고 있습니다. 제발 여기 잘못 생각하십시오!).

그래서 대신 내가 여기에 구조 정의를 변경 것이라고 생각 :

typedef struct MexFunArgs { 
    int nrhs; 
    const mxArray *(*prhs)[]; 
} MexFunArgs; 

즉, mxArray에 대한 포인터의 배열에 대한 포인터. 이것은 할당 문제를 해결합니다 (컴파일러는 여전히 이해할 수없는 이유로 호환되지 않는 포인터 유형에 대해 불평합니다). 그러나 mexCallMATLAB 함수는 const mxArrays에 대한 포인터 배열을 사용하지 않고 대신 const가 아닌 mxArrays에 대한 포인터 배열을 사용합니다. 그래서 지금 const mxArrays에 대한 포인터 배열에 내 포인터의 const 부분을 캐스팅 할 방법이 있는지 알고 싶습니다. 어떻게 해야할지 모르겠지만 ... 다음은 합법적이지 않습니다.

(mxArray *(*)[]) 

할 수 있습니까? 그렇지 않다면, 내가 뭘하려고하는거야 (이러한 인수를 컴파일러 징징없이 사용할 수있는 같은 방법으로 상처가없는 다른 스레드에 전달) C에서 다른 방법으로 가능합니까?

다음은 현재 사용하고있는 전체 코드입니다. 예상했던대로 실행되지만 컴파일 될 때 경고 메시지가 나타납니다. 나는 경고를 싫어하고 그것을 버리고 싶다. 그렇게하는 올바른 방법은 무엇입니까?

#include <pthread.h> 
#include <unistd.h> 
#include <mex.h> 

typedef struct MexFunArgs { 
    int nrhs; 
    mxArray *(*prhs)[]; 
} MexFunArgs; 

void *do_thread(void *args) { 
    MexFunArgs *mfa = (MexFunArgs*) args; 

    mexCallMATLAB(0, NULL, mfa->nrhs, *mfa->prhs, "disp"); 

    pthread_exit(NULL); 
} 

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 
    int num; 

    if (nrhs < 1) 
    mexErrMsgTxt("not enough input arguments"); 
    else 
    num = mxGetScalar(prhs[0]); 

    MexFunArgs mfa; 

    mfa.nrhs = nrhs; 
    mfa.prhs = &prhs[1]; /* <-- threads.c:29: warning: assignment from incompatible pointer type */ 

    pthread_t threads[num]; 

    int rc, t; 
    for (t = 0; t < num; t++) { 
    mexPrintf("In main: creating thread %d\n", t); 
    rc = pthread_create(&threads[t], NULL, do_thread, (void *) &mfa); 
    if (rc) 
     mexErrMsgTxt("Problem with return code from pthread_create()"); 
    } 
    return; 
} 
+0

정보가 너무 많습니다. 정보가 충분하지 않습니다. * mexFunction이 무엇을 좋아합니까? 어디서 그리고 언제가 중요한가? –

+0

설명 : mexFunction을 수정할 수 없다고하셨습니다. 내가 물어야 할 것은 MexFunArgs 구조체의 데이터로 무엇을하고 싶습니까? 언제/어디서 배열을 할당하고, 어디에 할당할까요? 포인터는 어디에서 const가되어야합니까 (mexFunction 안에있을 필요가 없기 때문에)? –

답변

1

모든 것이 행복하게 작동하도록하는 방법을 알아 냈습니다. 배열과 포인터는 함수 시그니처에서 동일하게 취급되므로 mxArray * thing [] 대신 mxArray **를 사용하도록 mexFunction을 변경했습니다. 배열 타입으로 변환 할 필요가 없으므로 캐스팅에 문제가 없습니다 (불법).

0

내가 아직 너무 가리키는 객체의 const와 대 포인터의 const와의 차이를 파악하지 않은 가정 당신의 표제에 기초한 추측을 복용합니다.

안내 할 수있는 예제는 Why does this allow promotion from (char *) to (const char *)?을 참조하십시오.

및 다른 질문은 부분에 대해 별도의 질문으로 나누어보십시오. 그게 당신이 찾는 대답을 얻는데 도움이 될 수 있습니다.

1

경고 인해 비의 포인터들의 어레이 mxArray S

포인터를 const 포인터

배열 (이름)의 과제 인 const mxArray.

보다 제한적인 유형으로 만 안전하게 할당 할 수 있습니다.

이들은 다른 유형입니다. 특정 라인에 대한 경고를 사용하지 않거나 캐스트를 사용하는 경우 모두 똑같이 위험합니다.

또한 C99 기반 컴파일러로 컴파일하는 경우 mxArray 선언에서 구조체가 비어있는 []을 선언하고 가변 길이 배열을 선언합니다. 이게 니가 원하는거야?