C의 pthread 스레드에서 값을 반환하려면 어떻게 해야 합니까?
저는 C가 처음이라 실타래를 조금 가지고 놀고 싶습니다.다음을 사용하여 스레드에서 값을 반환하고 싶습니다.pthread_exit()
제 코드는 다음과 같습니다.
#include <pthread.h>
#include <stdio.h>
void *myThread()
{
int ret = 42;
pthread_exit(&ret);
}
int main()
{
pthread_t tid;
void *status;
pthread_create(&tid, NULL, myThread, NULL);
pthread_join(tid, &status);
printf("%d\n",*(int*)status);
return 0;
}
프로그램 출력을 예상합니다."42\n"
랜덤 번호를 출력합니다.반환된 값을 인쇄하려면 어떻게 해야 하나요?
로컬 변수에 포인터를 반환하는 것은 문제가 있는 것 같습니다.여러 스레드의 변수를 반환/저장하는 베스트 프랙티스는 무엇입니까?글로벌 해시 테이블?
스레드 기능이 종료되면 더 이상 존재하지 않는 로컬 변수의 주소를 반환합니다.어쨌든, 왜 전화하는 거야?pthread_exit
스레드 함수에서 단순히 값을 반환하지 않는 이유는 무엇입니까?
void *myThread()
{
return (void *) 42;
}
그 후, 주로 다음과 같습니다.
printf("%d\n", (int)status);
구조체와 같은 복잡한 값을 반환해야 하는 경우 다음 방법으로 동적으로 할당하는 것이 가장 쉬울 수 있습니다.malloc()
포인터를 반환합니다.물론 스레드를 시작한 코드가 메모리를 해방시킵니다.
여기 올바른 해결책이 있습니다.이 경우 tdata는 메인스레드에 할당되며 스레드에는 결과를 배치할 공간이 있습니다.
#include <pthread.h>
#include <stdio.h>
typedef struct thread_data {
int a;
int b;
int result;
} thread_data;
void *myThread(void *arg)
{
thread_data *tdata=(thread_data *)arg;
int a=tdata->a;
int b=tdata->b;
int result=a+b;
tdata->result=result;
pthread_exit(NULL);
}
int main()
{
pthread_t tid;
thread_data tdata;
tdata.a=10;
tdata.b=32;
pthread_create(&tid, NULL, myThread, (void *)&tdata);
pthread_join(tid, NULL);
printf("%d + %d = %d\n", tdata.a, tdata.b, tdata.result);
return 0;
}
로컬 변수에 포인터를 반환했습니다.쓰레드가 관여하지 않아도 그건 안 좋아.
일반적으로 시작하는 스레드가 조인된 스레드와 동일한 경우 pthread_create의 4번째 파라미터로 발신자가 관리하는 위치에 있는 int에 포인터를 전달하는 방법이 있습니다.그러면 스레드 진입점에 대한 (유일한) 매개 변수가 됩니다.스레드 종료 값을 사용하여 성공을 나타낼 수 있습니다.
#include <pthread.h>
#include <stdio.h>
int something_worked(void) {
/* thread operation might fail, so here's a silly example */
void *p = malloc(10);
free(p);
return p ? 1 : 0;
}
void *myThread(void *result)
{
if (something_worked()) {
*((int*)result) = 42;
pthread_exit(result);
} else {
pthread_exit(0);
}
}
int main()
{
pthread_t tid;
void *status = 0;
int result;
pthread_create(&tid, NULL, myThread, &result);
pthread_join(tid, &status);
if (status != 0) {
printf("%d\n",result);
} else {
printf("thread failed\n");
}
return 0;
}
구조물에 반드시 스레드 종료 값을 사용해야 하는 경우 동적으로 할당해야 합니다(그리고 스레드에 참여하는 사용자가 스레드를 해방하는지 확인하십시오).하지만 그건 이상적이지 않아요.
내 생각에 너는 번호를 더미에 저장해야 할 것 같아.그int ret
변수는 스택에 있으며 함수 실행 종료 시 파괴되었습니다.myThread
.
void *myThread()
{
int *ret = malloc(sizeof(int));
if (ret == NULL) {
// ...
}
*ret = 42;
pthread_exit(ret);
}
잊지 말고free
필요 없을 때
또 다른 해결책은 Neil Butterworth가 제안하는 바와 같이 숫자를 포인터의 값으로 반환하는 것입니다.
#include<stdio.h>
#include<pthread.h>
void* myprint(void *x)
{
int k = *((int *)x);
printf("\n Thread created.. value of k [%d]\n", k);
//k =11;
pthread_exit((void *)k);
}
int main()
{
pthread_t th1;
int x =5;
int *y;
pthread_create(&th1, NULL, myprint, (void*)&x);
pthread_join(th1, (void*)&y);
printf("\n Exit value is [%d]\n", y);
}
스택의 변수인 ret에 대한 참조를 반환합니다.
질문: 여러 스레드의 변수를 반환/저장하는 베스트 프랙티스는 무엇입니까?글로벌 해시 테이블?
반품 대상과 사용 방법에 따라 달라집니다.스레드 상태만 반환하는 경우(스레드가 의도한 작업을 완료했는지 여부를 나타냅니다), pthread_exit을 사용하거나 return 문을 사용하여 스레드 함수에서 값을 반환합니다.
그러나 추가 처리에 사용할 추가 정보를 원할 경우 글로벌 데이터 구조를 사용할 수 있습니다.단, 이 경우 적절한 동기화 프리미티브를 사용하여 동시성 문제를 처리해야 합니다.또는 동적 메모리(가급적 데이터를 저장하는 구조)를 할당하여 pthread_exit 경유로 송신하고 스레드가 가입하면 다른 글로벌구조로 갱신할 수 있습니다.이렇게 하면 하나의 메인 스레드만 글로벌 구조를 업데이트하고 동시성 문제는 해결됩니다.단, 다른 스레드에 의해 할당된 모든 메모리를 해방해야 합니다.
주소 반환이 불편하고 반환할 변수(예: 정수 값)가 하나만 있는 경우 전달하기 전에 (정수 *)로 타이핑하고, 메인에서 수집하면 (int)로 다시 타이핑할 수 있습니다.당신은 추악한 경고를 하지 않고 가치를 가지고 있다.
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
void *myThread(void *args)
{
return (void *)(intptr_t)42;
}
int main(void)
{
pthread_t tid;
void *status;
int ret;
pthread_create(&tid, NULL, myThread, NULL);
ret = pthread_join(tid, &status);
if (ret) {
fprintf(stderr, "pthread_join() failed\n");
return -1;
}
/* pthread_join() copies the exit status (namely 42) of the target thread
* into the location pointed to by retval (namely &status), &status points
* to void *, so we need to cast void * to int.
*/
printf("%ld\n", (intptr_t)status);
return 0;
}
언급URL : https://stackoverflow.com/questions/2251452/how-to-return-a-value-from-pthread-threads-in-c
'IT이야기' 카테고리의 다른 글
Java에서 싱글톤 패턴을 구현하는 효율적인 방법은 무엇입니까? (0) | 2022.06.10 |
---|---|
Nuxt-auth v5 모듈이 로그인한 사용자를 스토어 상태로 설정하지 않음 (0) | 2022.06.10 |
JPA와 Spring Data JPA의 차이점은 무엇입니까? (0) | 2022.06.09 |
컨테이너가 카드 안에 있을 때 데이터 테이블을 전체 너비로 확대하려면 어떻게 해야 합니까? (0) | 2022.06.09 |
vuex 저장소를 입력하는 일반 유형 (0) | 2022.06.09 |