http://egloos.zum.com/sweeper/v/2815395
일단 이 이미지와 설명을 같이 보면
thread는 heap, stack, data 영역을 공유하고 thread만의 stack 영역을 확보함.
이 stack 영역을 확보 한다는 게 어떤 의미인지 알아야하는데
이 stack 영역을 확보 한다는 의미는 thread로 실행하는 함수의 지역변수를 다루기 위한 stack 영역이라고 보임
즉, main thread에 속한 int x= 777; 에서의 x를 thread 가 자신의 stack 메모리에 복사하지 않는다는 것임.
따라서 파라미터로 전달되는 x는 main thread의 지역 변수 x가 그대로 전달됨. 이거를 *를 쓰면 주소가 전달돼서 778이 되는거고
값으로 전달하면 값의 복사에 의하여 777이 되는거고
반대로 thread가 참고하는 함수의 지역변수 y는 주소값이 다 다름
결과 값은 아래에 있음.
아무래도 stack 메모리를 확보하는 점에서 main thread에 있는 지역변수의 값을 복사하여 가져온다고 생각을 한 것 같은데
그게 아닌듯함.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <iostream> #include <cstdio> #include <thread> #include <vector> #include <random> #include <mutex> #define SIZE 10 #include <thread> #include <iostream> using namespace std; void foo(int* x) { int y; y = 10; (*x)++; printf("x : %x y: %x
", x, &y); } int main() { int x = 777; int y = 1; int k = 0; printf("x : %x y: %x
", &x,&y); //auto f = [&] { ++x; }; std::thread t1(foo, &x); std::thread t2(foo, &x); t1.join(); t2.join(); printf("x : %x y: %x
", &x, &y); return 0; } | cs |
이게 내가 생각하는 스레드 생성 이후의 메모리 구조임.
그러면 p의 값이 갖고 p가 가리키는 값도 같은게 맞지 않을까
되서->돼서 (되어 = 돼임) [리듬 맞춤법 봇♬]
개별적 스택을 갖는다는 말이 이상한것같음
실험해보니까 스택의 일부를 공유함
운영체제에서 컨텍스트 돌릴때 스택의 일부도 컨텍스트로 잡고있어야 말이됨
밑에 거 보면 a와 b의 주소는 다 다르잖아, 반면에 p의 주소는 똑같고 그런데 이 p는 main thread의 지역변수를 가져온거라 그런거 같거든
설명이 괜찮은 것 같음? 아니면 틀린 것 같음/
스택프레임 시작보다 높은 부분에 있는 메모리에 접근이 된다는게 이상하단거임
그게 람다가 암시적으로 p를 전달하는 것 같은데
내 가정은 람다 함수는 컴파일러가 람다 함수를 위한 선언과 정의를 만들어 주고 매개변수 값을 암시적으로 전달했을 때 맞긴함..
ㄴㄴ 내가 설명이 이상했음
일단 람다는 캡쳐링한걸 멤버로 삼기때문에 복사에의해 전달되면 쓰레드 공유문제는 발생하지않음
보니까 쓰레드마다 0x1000씩 스택 꼭대기의 주소가 다른데 강제로 접근해봄
실험더해볼게
니 람다를 보면 [=]{...}일케 되어있는데 [=]는 외부에 정의 되어있는 변수들을 이 람다 함수안의 멤버 변수식으로 끌어온다는 거잖아, 그리고 너는 p라는 포인터를 가져왔고 그러니까 각 스레드에서 p값이 같은게 아닐까
그니까 그건 의도한거고 같아야함
같은게 문제가 아니라 유효하다는게 문제임
같은 메모리를 가르키고 있더라도 그건 스택메모리인데 다른 쓰레드에서 주소가 같다고해서 같은 값이 들어있으라는 보장이 없어
유효하다는 게 어떤의미?
근데 실험해보니까 같다는거지.. 그래서 스택의 일부를 컨텍스트로 삼는거 아닐까 하는거고
쓰레드는 개별적인 스택을 갖는다 => 다른 쓰레드의 메모리에 접근해선 안된다? 이게 내 생각엔 맞는데
이 생각을 정면으로 반박하고있음
유효하다는건 다른쓰레드의 메모리에 접근하는게 허용되고있따는거니까
내가 이미지를 하나 그려봤음 위에
쓰레드가 개별적인 스택을 갖는게 다른 쓰레드의 메모리에 접근해서는 안된다로 이어지는게 맞나? 근데 이게 맞음. 왜냐면 쓰레드끼리 상대방의 stack메모리에 있는 지역 변수 등을 볼 수 있는 방법도 없으니까, 하지만 포인터 p는 main thread에서 각 쓰레드로 전달이 되었으니까, 각 쓰레드에서 이 p를 볼 수 있고, 따라서 다룰 수도 있다고봄
아 내가 생각하던 모든게 다 깨졌음
충격적인 결과를 얻어따
결과적으론 접근수단만 있으면 같은 프로세스에선 어떤 쓰레드라도 와따가따 할 수 있음
ㅇㅇㅋ 그렇징
그리고 개별스택이라는 말 자체도 허구임
스택자체를 공유함.. 리눅스만 그런가?
휴 마침내 나는 자러 갈 수 있따.
옹 니네 재밋어보인다