pthread_create ()에 의해 호출되는 함수에 대한 여러 인수?


93

별도의 스레드에서 호출하려는 함수에 여러 인수를 전달해야합니다. 나는 한 읽기 이 작업을 수행하는 일반적인 방법은, 구조체를 정의하는하는 기능을 포인터를 전달하고 인수를 역 참조하는 것입니다. 그러나이 작업을 수행 할 수 없습니다.

#include <stdio.h>
#include <pthread.h>

struct arg_struct {
    int arg1;
    int arg2;
};

void *print_the_arguments(void *arguments)
{
    struct arg_struct *args = (struct arg_struct *)args;
    printf("%d\n", args -> arg1);
    printf("%d\n", args -> arg2);
    pthread_exit(NULL);
    return NULL;
}

int main()
{
    pthread_t some_thread;
    struct arg_struct args;
    args.arg1 = 5;
    args.arg2 = 7;

    if (pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0) {
        printf("Uh-oh!\n");
        return -1;
    }

    return pthread_join(some_thread, NULL); /* Wait until thread is finished */
}

이에 대한 출력은 다음과 같아야합니다.

5
7

그러나 내가 그것을 실행하면 실제로 다음을 얻습니다.

141921115
-1947974263

아무도 내가 뭘 잘못하고 있는지 알아?


2
힙에 할당 하시겠습니까?
Carson Myers

1
@Carson 왜 그것이 차이를 만들어야합니까?
sigjuice

5
구조는 최소한 스레드만큼 오래 살아야합니다. 스레드를 생성하고 pthread_create ()를 호출 한 함수에서 반환하는 경우 스택에 할당 된 구조가 다른 데이터에 의해 덮어 쓰여지고 스레드 함수에 문제가 발생할 수 있습니다. 이 예제에서는 생성 스레드가 반환하기 전에 작업자 스레드가 완료 될 때까지 기다리므로 문제가되지 않습니다.
Commodore Jaeger

@Commodore Jaeger 오! 고맙습니다. 그게 제가 함께 일하던 다른 사람과 함께 겪었던 문제입니다. Carson이 말했듯이 malloc ()을 사용하여 힙에 할당하여 수정했습니다. 이제 훨씬 더 의미가 있습니다.
Michael

답변:


77

당신이 말하기 때문에

struct arg_struct *args = (struct arg_struct *)args;

대신에

struct arg_struct *args = arguments;


5
@sigjuice, 그것은 나를 위해 작동하지 않습니다. 컴파일 오류 : 'void *'에서 'arg_struct *'로의 잘못된 변환이 표시됩니다.
Neshta 2014 년

20

사용하다

struct arg_struct *args = (struct arg_struct *)arguments;

대신에

struct arg_struct *args = (struct arg_struct *)args;

4

main()자체 스레드 및 스택 변수가 있습니다. 힙의 'args'에 대한 메모리를 할당하거나 전역으로 만듭니다.

struct arg_struct {
    int arg1;
    int arg2;
}args;

//declares args as global out of main()

물론 참조를 args->arg1에서 args.arg1등으로 변경하십시오 .


2

사용하다:

struct arg_struct *args = malloc(sizeof(struct arg_struct));

다음과 같이이 인수를 전달합니다.

pthread_create(&tr, NULL, print_the_arguments, (void *)args);

무료 인수를 잊지 마세요! ;)


1

print_the_arguments의 인수는 인수이므로 다음을 사용해야합니다.

struct arg_struct *args = (struct arg_struct *)arguments. 

1
struct arg_struct *args = (struct arg_struct *)args;

->이 할당이 잘못되었습니다.이 컨텍스트에서 변수 인수를 사용해야합니다. 건배!!!


1

이 코드의 스레드 생성에서 함수 포인터의 주소가 전달됩니다. 원래 pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0

다음과 같이 읽어야합니다. pthread_create(&some_thread, NULL, print_the_arguments, (void *) &args)

기억하는 좋은 방법은이 함수의 모든 인수가 주소 여야한다는 것입니다.

some_thread정적으로 선언되므로 &.

나는 만들 것이다 pthread_attr_t다음 변수를 사용 pthread_attr_init()거기에 그 변수의 주소를 전달합니다. 그러나 NULL포인터 전달 도 유효합니다.

&기능 라벨의 전면 여기에 문제를 일으키는 것입니다. 사용 된 레이블은 이미 void*함수에 대한 것이므로 레이블 만 필요합니다.

!= 0마지막 주장으로 말하는 것은 결정되지 않은 행동을 유발하는 것처럼 보입니다. 이를 추가하면 참조 대신 부울이 전달됩니다.

Akash Agrawal의 답변은이 코드 문제에 대한 해결책의 일부이기도합니다.


1

원래 포스터 마이클과 같은 질문이 있습니다.

그러나 나는 성공하지 않고 원래 코드에 대해 제출 된 답변을 적용하려고 시도했습니다.

시행 착오 끝에 작동하는 코드의 내 버전이 있습니다 (또는 적어도 나를 위해 작동합니다!). 자세히 살펴보면 이전에 게시 된 솔루션과 다르다는 것을 알 수 있습니다.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct arg_struct
{
   int arg1;
   int arg2;
} *args;

void *print_the_arguments(void *arguments)
{
   struct arg_struct *args = arguments;
   printf("Thread\n");
   printf("%d\n", args->arg1);
   printf("%d\n", args->arg2);
   pthread_exit(NULL);
   return NULL;
}

int main()
{
   pthread_t some_thread;
   args = malloc(sizeof(struct arg_struct) * 1);

   args->arg1 = 5;
   args->arg2 = 7;

   printf("Before\n");
   printf("%d\n", args->arg1);
   printf("%d\n", args->arg2);
   printf("\n");


   if (pthread_create(&some_thread, NULL, &print_the_arguments, args) != 0)
   {
      printf("Uh-oh!\n");
      return -1;
   }

   return pthread_join(some_thread, NULL); /* Wait until thread is finished */
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.