질문 c++ 스레드로 함수 호출

익명 사용자의 이미지

안녕하세요 c++ thread를 공부하는 중에 막혀서 질문드립니다.

<목적> 아래 코드에서 foo함수는 바꾸지 않은채로 main에서 thread를 사용해서 foo함수를 정상적으로 호출하고싶습니다.

근데 자꾸 C2672, C2893, C2780이 뜨는데 어떻게 고쳐야 할 지 모르겠습니다.

foo함수에서 int *a, int *b를 그냥 int a, int b로 고치면 잘 되는건 알고있습니다.

근데 사정이 있어서 함수는 저대로 써야합니다...

도와주세요

---------------------------------- 코드 ----------------------------

#include
#include

using namespace std;

void foo(int *a, int *b);

int main() {

int num1 = 100;
int num2 = 200;

thread t1(foo, num1, num2);
t1.join();
return 0;
}

void foo(int *a, int *b) {
printf("%d %d 함수 호출\n", a, b);
}

익명 사용자의 이미지

하고 싶은 게 정확히 뭔데요?

모로 가도 컴파일만 된다고 생각하고 문제를 해결하려면 대충 떠오르는 솔루션만 세 가지쯤 되는군요.

(1) 캐스팅으로 타입 때려 박기

int main() {
	int num1 = 100;
	int num2 = 200;
 
	thread t1(foo, (int *)num1, (int *)num2);
	t1.join();
 
	return 0;
}

(2) 좀 더 똑똑하게 타입 맞춰 넣기

int main() {
	int num1 = 100;
	int num2 = 200;
 
	thread t1(foo, &num1, &num2);
	t1.join();
 
	return 0;
}

(3) 완충하기

int main() {
	int num1 = 100;
	int num2 = 200;
 
	thread t1([](int num1, int num2){ foo(&num1, &num2); }, num1, num2);
	t1.join();
 
	return 0;
}

======

프로그래밍 언어는 수단에 불과합니다. 중요한 건 목적이죠.

수단에 뭔가 이상야릇한 조건을 걸어 놓고 정작 뭘 하려는 것인지 목적을 밝히지 않으면, 제대로 된 조언을 구하기 매우 어렵습니다.

작성자의 이미지

정확한 목적은 제가 c++로 한 프로그램을 짜다가 후반에 thread로 함수를 실행시켜야 하는데
foo함수처럼 이미 만들어진 함수를 고치기가 힘들어서 이 함수를 유지한 채로 가능하면
thread를 써서 실행을 시키고싶었습니다.

초보 프로그래머의 호기심이라고 봐주시면 될 것 같습니다

작성자의 이미지

#include
#include

using namespace std;

class Car {
public:
int value1;
int value2;
};

void foo(Car** (&car), int* a, int* b);

int main() {

int height = 3;
int weight = 10;

Car** car;
car = new Car * [weight];
for (int i = 0; i < weight; i++) {
car[i] = new Car[height];
}

int num1 = 100;
int num2 = 200;

thread t1(foo, car, &num1, &num2); // 이 부분에서 문제가 발생합니다...
t1.join();

return 0;
}

void foo(Car** (&car), int* a, int* b) {
printf("%d %d 함수 호출 \n", *a, *b);
}

----------------------------------------------------

위에 코드처럼 thread로 foo함수를 실행할 때 동적할당 된 car라는 객체를 포함해서 실행을 하고 싶습니다.
car만 넣으면 C2672, C2893, C2780오류가 뜨는데 이 오류들을 검색해봐도 말이 어려워서 잘 모르겠습니다

thread에서 함수를 실행할 때 클래스가 포함되면 무조건 오류가 뜨는건가요?
아니면 제가 잘 못 코딩한건가요?

라스코니의 이미지

void foo(Car** (&car), int* a, int* b) 에서 왜 Car** (&car) 라고 하셨나요?
Car **car 가 맞을 것 같은데요.

익명 사용자의 이미지

이게 바로 개발자의 목적을 밝히는 게 중요한 이유입니다.
이런 답글이 달리게 되잖아요.

다른 스레드를 만들면서 현재 스레드의 지역 변수의 참조를 넘겨주는 경우가 그렇게 일반적이지는 않습니다.
하지만 개발자의 뚜렷한 의도에 따라 주의하여 사용한다면, 불가능한 것까지는 아니지요.

그런데 지금 보여주신 코드는 개발자의 의도가 전혀 드러나지 않는 toy example 수준의 코드라서,
애초에 car를 왜 참조로 만들었느냐는 되물음을 받을 수밖에 없는 겁니다.
물론 그렇게 따지면, 주어진 코드에서는 사실 thread를 쓸 필요도 없지요.

======

각설하고, 에러가 발생하는 원인은 std::thread가 매개변수를 참조로 전달해 주지 않기 때문입니다.

https://stackoverflow.com/questions/10503258/what-is-the-rationale-behind-stdbind-and-stdthread-always-copying-arguments

참조를 전달해 주게 만들려면 아래와 같이 std::ref를 사용해야 합니다.

#include <cstdio>
#include <thread>
#include <functional>
using namespace std;
 
class Car {
public:
	int value1;
	int value2;
};
 
void foo(Car **&car, int *a, int *b);
 
int main() {
	int height = 3;
	int weight = 10;
 
	Car **car;
	car = new Car *[weight];
	for (int i = 0; i < weight; i++) {
		car[i] = new Car[height];
	}
 
	int num1 = 100;
	int num2 = 200;
 
	thread t1(foo, ref(car), &num1, &num2);
	t1.join();
 
	return 0;
}
 
void foo(Car **&car, int *a, int *b) {
	printf("%d %d 함수 호출 \n", *a, *b);
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.