스레드가 아닌 모드에서 정상적으로 작동하는 GCC C 응용 프로그램에서 스레드를 사용하려고합니다 (처음으로!). 내가 그것을 실행할 때 일부 스레드는 필요한 답 (모든 검사 목적으로 알고 있음) 대신 모두 0 인 결과를 제공하지만, 0을주는 스레드는 실행할 때마다 동일하지 않습니다. 0이 아닌 답을주는 코드는 정확하므로 코드가 정상적으로 실행됩니다. 누군가가 스레드로부터 안전하지 않은 부분을 지적 할 수 있는지 궁금합니다.스레드는 잠금없이 동일한 구조체 배열의 다른 요소에 쓸 수 있습니까?
내 생각에 결과 나 메모리 할당을 어떻게 모으는가 때문일 수 있습니다 - StackOverflow에서 malloc과 free를 사용하지만 -lpthread와 연결된 경우 GCC malloc은 thread-safe로 간주됩니다. 하기). 전역/정적 변수를 사용하는 것은 없으며 모든 것이 함수 인수로 전달됩니다.
결과를 main으로 전달하기 위해 스레드 된 루틴은 구조체 배열을 사용합니다. 각 스레드는이 배열의 고유 한 요소에 쓰므로 동일한 메모리에 쓰려고하지 않습니다. 어쩌면 구조 배열의 같은 요소로 이동하지 않아도 결과를 작성할 때 어떤 형태의 잠금을 사용해야합니까?
는 여기 스레드 코드에 대한 레시피를 따라 : https://computing.llnl.gov/tutorials/pthreads/#AbstractI 부착이 어떤 단서를 제공하는 경우에 (간체) 코드 추출물 (I 잘못/수정 뭔가 생략 한 수 있지만 사람이 발견하는 나는 요구 하진 않았어 버그, 그냥 일반적인 방법론). 이 글을 읽는 다른 사람의 이익을 위해
typedef struct p_struct { /* used for communicating results back to main */
int given[CELLS];
int type;
int status;
/*... etc */
} puzstru;
typedef struct params_struct { /* used for calling generate function using threads */
long seed;
char *text;
puzzle *puzzp;
bool unique;
int required;
} paramstru;
/* ========================================================================================== */
void *myfunc(void *spv) /* calling routine for use by threads */
{
paramstru *sp=(paramstru *)spv;
generate(sp->seed, sp->text, sp->puzzp, sp->unique, sp->required);
pthread_exit((void*) spv);
}
/* ========================================================================================== */
int generate(long seed, char *text, puzstru *puzzp, bool unique, int required)
{
/* working code , also uses malloc and free,
puts results in the element of a structure array pointed to by "puzzp",
which is different for each thread
(see calling routine below : params->puzzp=puz+thr;)
extract as follows: */
puzzp->given[ix]=calcgiven[ix];
puzzp->type=1;
puzzp->status=1;
/* ... etc */
}
/* ========================================================================================== */
int main(int argc, char* argv[])
{
pthread_t thread[NUM_THREADS];
pthread_attr_t threadattr;
int thr,threadretcode;
void *threadstatus;
paramstru params[1];
/* ....... ETC */
/* set up params structure for function calling parameters */
params->text=mytext;
params->unique=TRUE;
params->required=1;
/* Initialize and set thread detached attribute */
pthread_attr_init(&threadattr);
pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_JOINABLE);
for(thr=0; thr<NUM_THREADS; thr++)
{
printf("Main: creating thread %d\n", thr);
params->seed=ran_arr_next(startingseeds);
params->puzzp=puz+thr;
threadretcode = pthread_create(&thread[thr], &threadattr, myfunc, (void *)params);
if (threadretcode)
{
printf("ERROR; return code from pthread_create() is %d\n", threadretcode);
exit(-1);
}
}
/* Free thread attribute and wait for the other threads */
pthread_attr_destroy(&threadattr);
for(thr=0; thr<NUM_THREADS; thr++)
{
threadretcode = pthread_join(thread[thr], &threadstatus);
if (threadretcode)
{
printf("ERROR; return code from pthread_join() is %d\n", threadretcode);
exit(-1);
}
printf("Main: completed join with thread %d having a status of %ld\n",thr,(long)threadstatus);
}
/* non-threaded code, print results etc ............. */
free(startingseeds);
free(puz);
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL);
}
- 모든 답이 정확하고, 제목의 질문에 대한 대답은 YES, 스레드 구조의 동일한 배열의 다른 요소에 안전하게 쓸 수있다, 내 문제였다 호출 루틴에 - 다음은 수정 된 코드입니다 (지금은 잘 작동) :
paramstru params[NUM_THREADS];
for(thr=0; thr<NUM_THREADS; thr++)
{
printf("Main: creating thread %d\n", thr);
/* set up params structure for function calling parameters */
params[thr].text=mytext;
params[thr].unique=TRUE;
params[thr].required=1;
params[thr].seed=ran_arr_next(startingseeds);
params[thr].puzzp=puz+thr;
threadretcode = pthread_create(&thread[thr], &threadattr, myfunc, (void *)¶ms[thr]);
if (threadretcode)
{
printf("ERROR; return code from pthread_create() is %d\n", threadretcode);
exit(-1);
}
}
흠. puz 변수는 어디에 선언 되었습니까? 그것은 '퍼즐 *'유형입니까? 'ix'는 어떻게 계산됩니까? 문제가 "작업 코드"로 표시된 블록에 있다고 생각합니다. ;) –