2012-08-28 3 views
0

내 질문에 스레드가 매개 변수를 스레드로 전달합니다.스레드 매개 변수 전달 c

배열에 대해 작동하는 Foo 함수가 있습니다 (예 : arrayA). 속도를 높이기 위해 Foo는 어레이의 양방향으로 작동하도록 코딩되어 있습니다. 따라서 Foo는 arrayA와 정수 X를 매개 변수로 사용합니다. X의 값에 따라 정방향 또는 역방향으로 작동합니다.

"arrayA"및 "X"를 전역 적으로 사용하지 않으려합니다. 그래서, 나는 "arrayA"와 "X"를 Foo에 매개 변수로 전달하고 Foo를 실행하는 두 개의 스레드를 생성합니다. 각 방향으로 하나씩 실행합니다. 여기 내가 한 일이 있습니다 :

typedef struct {int* arrayA[MSIZE]; int X; } TP; //arrayPack=TP 

void Foo (void *tP) { 

    TP *tp = (TP*)tP; // cast the parameter tP back to what it is and assign to pointer *tp 

    int x; 
    printf("\nX: %d", tp->X); 
    printf("\n arrayA: "); for (x=0; x<tp->arrayA.size(); printf("%d ", aP->arrayA[x]), x++); 
} // end Foo 

void callingRouting() { 
    int* arrayA[MSIZE] = {3,5,7,9}; 
    TP tp; tp.arrayA=arrayA; 
    tp.X=0; _beginthread(Foo, 0, (void*)&tp); // process -- forward 
    tp.X=1; _beginthread(Foo, 0, (void*)&tp); // process -- reverse 
} 

값이 전달되지 않았습니다 - 배열이 비어있는 상태로 인쇄되고 X 값이 제대로 표시되지 않습니다. 나는 무엇을 놓치고 있습니까?

이것에 대한 약간의 독서에 대한 제안도 감사 할 것입니다 - 매개 변수를 스레드로 전달 - 특히 스레드가 공유하는 리소스를 전달할 때. 감사.

+0

'int * arrayA [MSIZE];'는 아마도 잘못된 크기 일 것입니다. 사이드 노트로 – oldrinb

+0

, 나는 반전 반복을하고있는 곳을 보지 못했다. 배열과 오프셋에 오프셋을 사용하는 것이 좋습니다. 그러면 더 많은 스레드로 확장 할 수 있습니다. – MartyE

답변

2

스택 변수의 주소를 스레드 함수에 전달하면 callingRouting이 나오고 TP 구조가 더 이상 존재하지 않습니다. 전역 변수이거나 힙에 할당되어야합니다.

tp.X=1이 두 스레드 모두에게 표시 될 수 있기 때문에 각 스레드에 대해 TP 사본이 두 개 필요합니다.

거기에 문제가 있지만 어떻게 보는지는 OS가 각 실행시 스레드를 예약하는 방법에 따라 다릅니다.

+0

네, 고마워요. 로컬 변수에'tp.X'를로드하여 Foo의 다른 스레드가 볼 수 없도록합니다. 아직까지는 시도하지 않았다. 그리고 나는 다른 로컬 변수에로드하기 전에 다른 Foo/스레드가'tp.X' 값을 변경할 수 있다고 생각합니다. 나는 전화가 일단 나오면 TP가 더 이상 존재하지 않는다고 괜찮습니다. 내 문제는'arrayA'와'X'를 Foo에 전달할 수 없다. 그리고 그들을 "가치에 의해"그리고 "참고로"전달하는 법. – ashley

2

가장 먼저 기억해야 할 것은 두 개의 다른 스레드를 시작하는 스레드가 있다는 것입니다. 프로세서 시간 슬라이스와 그 할당 방법에 대한 제어권이 없기 때문에 두 개의 다른 스레드가 시작될 때를 확신 할 수 없으며 시작할 순서조차도 알 수 없습니다.

그 함수가 지역 변수를 반환하자마자 함수 callingRouting()에 로컬 인 스택의 배열을 사용하면 기본적으로 할당 된 범위를 벗어나 더 이상 의존 할 수 없게됩니다.

이렇게하려면 몇 가지 방법이 있습니다.

첫 번째는 스레드에 전달되는 데이터 항목에 전역 또는 정적 메모리 변수를 사용하는 것입니다.

두 번째 스레드를 시작한 다음 두 스레드가 모두 완료 될 때까지 기다렸다가 계속하십시오.

시작될 스레드의 순서 또는 순서를 알 수 없으므로 각 스레드마다 하나씩 두 가지 TP 유형 변수를 사용해야합니다. 그렇지 않으면 두 스레드가 동일한 TP 데이터를 갖도록 시간 분할 할당의 위험을 감수해야합니다.

+0

OK, 여기에 2 가지주의 사항이 있습니다. 몇 가지를 명확히하고 잘못된 방향으로 일들을 피하려면 : Foo의 결과는 또 다른 배열, 예를 들어'Z'입니다. 'arrayA'는 "작업 영역"일 뿐이며, 변경 사항이 Foo 외부에서 보이지 않을지는 중요하지 않습니다. 그러나 Foo의 한 스레드가 수행 한'arrayA'에 대한 변경 사항은 다른 Foo 스레드가 볼 수 있어야합니다. 그래서'tp'에 대한 참조를 Foo에 전달하려고합니다. Foo는 호출 매개 변수에 의해 전달 된 mem.location에 대한 읽기/쓰기 작업을 수행해야합니다. & 그 같은 위치에 대한 참조를 Foo의 두 스레드에 전달하여 같은 arrayA에있는 R/W가되도록해야합니다. – ashley