쓰레드 공부하다가 이해 안가는게 있네요.

nexusz99의 이미지

#include "windows.h"
#include "stdio.h"
 
struct Point3D
{
	int x, y, z;
};
 
DWORD WINAPI MyThread(LPVOID arg)
{
	Point3D *pt = (Point3D *)arg;
	while(1){
		printf("Running another thread: %d, %d, %d\n", 
			pt->x, pt->y, pt->z);
		Sleep(1000);
	}
 
	return 0;
}
 
int main()
{
	// 첫 번째 스레드 생성
	Point3D pt1 = {10, 20, 30};
	DWORD ThreadId1;
	HANDLE hThread1 = CreateThread(NULL, 0, MyThread, 
		(LPVOID)&pt1, 0, &ThreadId1);
	if(hThread1 == NULL) return -1;
	CloseHandle(hThread1);
 
	// 두 번째 스레드 생성
	Point3D pt2 = {40, 50, 60};
	DWORD ThreadId2;
	HANDLE hThread2 = CreateThread(NULL, 0, MyThread, 
		(LPVOID)&pt2, 0, &ThreadId2);
	if(hThread2 == NULL) return -1;
	CloseHandle(hThread2);
 
	while(1){
		printf("Running primary thread...\n");
		Sleep(1000);
	}
 
	return 0;
}

위 코드에서요

실제로 실행해 보면 hThread1 -> main(while) -> hThread2 이런 순으로 실행이 되는데 왜 그런거죠?

제 생각에는 hThread1 -> hThread2 -> main(while) 으로 실행될거 같은데 말이죠

아 그리고 쓰레드를 생성하면 운영체제가 마음대로 쓰레드를 호출하는건가요?

쓰레드가 정확히 어떤식으로 돌아가는지 개념이 잘 안잡히네요.

rgbi3307의 이미지

동일한 리소스(크리티컬 섹션)를
2개 이상의 쓰레드가 동시에 접근하면,
운영체제는 내부적으로 SpinLock이나 Mutex 혹은 세마포어 논리로
리소스 충돌을 방지합니다.

위의 코드에서 크리티컬 섹션은 Point3D 구조체가 되겠고,
여기에 hThread1 이 접근해 있는 상태에서
hThread2가 접근하면 충돌이 발생하므로,
hThread2에 Lock이 걸리고,
main(while)이 수행된후, hThread1이 크리티컬 섹션사용을 반납한후
hThread2의 Lock이 해제 되면서 실행되는듯 합니다.

다시정리하면,
hThread1 실행 --> Point3D 구조체 취득 --> hThread2 접근 --> Locking
--> main(while) 실행 --> hThread1 종료 --> hThread2 Locking 해제
--> hThread2 실행 --> Point3D 구조체 취득 --> 종료.

MyThread()의 while(1) 루프안에 sleep(1000)이 있는데,
이것을 삭제하고 실행해 보세요.
어떻게 되나, 저도 테스트 해보고 싶은데,
예로 든 코드가 윈도에서 동작하는거 같네요.

전 개인적으로 리눅서라...
리눅스에서 좀더 정밀하게 코딩하여 확인해 봐야 겠네요.

From:
*알지비 (메신저: rgbi3307@nate.com)
*학창시절 마이크로마우스를 만들었고, 10년동안 IT관련 개발자로 일하고 있음.
*틈틈히 커널연구회(http://www.kernel.kr/) 내용물들을 만들고 있음.
*((공부해서 남을 주려면 남보다 더많이 연구해야함.))

From:
*알지비 (메일: rgbi3307(at)nate.com)
*커널연구회(http://www.kernel.bz/) 내용물들을 만들고 있음.
*((공부해서 남을 주려면 남보다 더많이 연구해야함.))

lovian의 이미지

위의 코드는 구조체에 대해서 스레드가 접근하는 간단한(특별한 처리가 없는) 스레드 코드인데도,
운영체제가 자동으로 lock을 거는건가요??

제가 분석해본 결과로는
단지 스레드 세 개가 되었을 뿐이고,
순서는 고정적이지 않다.
라고 생각했거든요.

으으 설마 진짜 lock??
-----------------
한글을 사랑합니다.

-----------------
한글을 사랑합니다.

chadr의 이미지

없는 락을 운영체제가 알아서 걸진 않습니다.
위의 실행결과는 컴퓨터마다 다를수 있습니다. 일단 첫번째 스레드가 생성되고 스레드는 대기상태로 진입됩니다.
이때 나머지 메인 스레드의 코드가 실행되다가 컨텍스트 스위칭이 일어나면 첫번째 스레드가 실행됩니다. 어떤 이유로 컨텍스트 스위칭 되기전에 메인함수 코드가 전부 실행되면 순서는 달라질 수 있습니다.

두번째 스레드도 마찬가지입니다. 생성되면 스레드는 대기상태로 전환되고 첫번째 스레드와 같은 수순을 밟습니다.

즉.. 스레드는 목적과 마찬가지로 어떤 스레드가 어떤 스레드보다 먼저 실행된다는 보장은 없습니다. 스레드로 프로그램을 짤때도 이를 염두해야하고요. 순서가 중요하다면 싱글스레드로 짜는게 맞습니다.

코어가 하나인 시스템에서는 계속 같은 결과가 나올지도 모르지만 요즘과같은 멀티코어가 있는 시스템에서는 항상 결과가 다를지도 모릅니다.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.