thread만들면 1:1이니까 여러개의 프로세스가 생성되나요.

toy의 이미지

리눅스에서 fork() 하면 사실은 쓰레드가 만들어진다고 얼핏들었는데요..
리눅스에서 fork() 한거와 create_thread한거와 어떻게 틀린지.....

그리고 쓰레드가 프로세스와 1:1로 대응된다는데.... 리눅스에서
pthread를 사용하면 진짜로 그런지요.
즉 create_thread() 3번하면
메인프로세스 포함하여 총 4개의 프로세스가 생성되는건가요?

리눅스에서의 쓰레드에 관련하여 자세히 나온책좀 추천해주세요.......
번역이 잘된 번역서나...우리나라사람이 쓴책이나요..원서볼시간이 없어서요...

ps.
이책 번역어떤지....요.
http://www.infopub.co.kr/common/bookinfo/bookinfo.asp?sku=12000011

kukuman의 이미지

Quote:
리눅스에서 fork() 하면 사실은 쓰레드가 만들어진다고 얼핏들었는데요.. 리눅스에서 fork() 한거와 create_thread한거와 어떻게 틀린지.....

흠,,, 뭔가 반대로 들으신 것 같습니다,,,
리눅스에서 fork()하면 process가 생성되구요,,,
리눅스에서의 thread는 원론적인 thread와는 약간은 다른 구조라고 알고 있습니다,,, kernel 2.6에서는 많이 바뀌었다고 하는데 정확한 내용은 모르겠네요,,,

thread의 정의는 정해져 있지만,,, 그 구현에 있어서는 여러가지 안들이 있는 것 같더군요,,,

다음을 참조해 보세요
http://bbs.kldp.org/viewtopic.php?t=24373&highlight=

그리고 kldp게시판에서도 검색하시면 많은 내용을 얻으실 수 있으실 겁니다,,,

ps. 그 책 저도 보았는데,,, 그냥 그렇습니다^^ (약간 난해하게 쓰여져 있던데요??)

Be at a right place at a right time...

kkojiband의 이미지

create_thread() 라 함은 kernel_thread() 를 말씀하시는거겠죠? 그 안을 보시면 알겠지만 그것도 사실은 clone system call 을 호출합니다. 근데 kernel_thread() 는 커널이 사용하려고 만들어놓은 함수입니다...
리눅스에서는 child process 를 생성할 때나 thread 를 생성할때 사용하는 fork, clone system call 이 내부적으로는 do_fork() 라는 함수를 호출하게 되고, clone 의 경우에는 여기에 flag 값을 세팅해서 여러 가지 자료구조들을 parent process 와 공유하게 되어있습니다. pthread library 는 이런 식으로 thread 를 생성해서 부모와 독립적으로 스케줄링되고, 메모리 영역 등을 공유하게 됩니다.
결론적으로 리눅스의 커널 스레드는, 프로세스는 프로세스인데, 몇 가지 중요한 자료구조를 부모와 공유하는 프로세스입니다...

참고서적은 물론 알고 계신 서적이겠지만, 제가 본 것 중에는 '리눅스 커널의 이해'가 설명이 가장 자세하고 좋았던거같습니다. 그리고 머니머니해도 커널 소스 자체가 가장 좋은 참고서적이구요...열심히 하세요!

이제 졸업이다...사랑하는 SKKULUG 후배들아 안녕~

toy의 이미지

답변감사합니다.^^

그렇다면 pthread를 사용한것과 clone() 시스템콜을 사용한것과 다를것이 거의 없게 되나요?? :oops:

progcom의 이미지

쓰레드를 어떠한 방법으로 사용하는가는 내부적으로 어떻게 처리하냐보다는 코드의 이식성 면에서 접근하시는게 좋습니다.

리눅스에서는 clone 시스템 콜을 사용할지 몰라도, 다른 OS에서는 전혀 다른 방법을 사용합니다.
pthread (POSIX thread)라는건 이러한 차이 없이 어느 시스템에서라도 코드를 그대로 쓸 수 있게 만들어진 표준입니다. 이 부분이 가장 큰 차이점이라고 보시면 됩니다.

리눅스에서 pthread를 지원하기 위해서 복수의 프로세스를 띄워서 관리한다고 보는게 옳을지도 모르겠습니다.

물론, 두가지는 다릅니다. :) clone()을 사용하면 pthread 라이브러리에서 제공하는 몇가지 처리를 직접 해야할 필요성이 생깁니다. (mutex 등)

toy의 이미지

제가 쓰레드를 생성한다음 ps -amux 로 프로세스 id를 구하고
/proc/PID/maps 들을 봤는데요.
이상하게도 전부 같더군요!

예상하기로는 linear address는 같지만 pgd가 쓰레드마다 틀리니까...
실제로 스택등은 다른곳에 메핑되었을수도 있겠다는 생각이 듭니다..

그렇다면 실제로 쓰레드를 2개 생성했다고 할때 이 두개가
실제로 공유하는것과 공유하지 않는것을 구분할수있는 방법은 없나요??
maps파일은 단순히 linear address만 나타내줘서 정확하지 않은것같아서요.

kkojiband의 이미지

linear address 를 공유한다는 말이, 곧 같은 pgd 를 사용한다는 말입니다. 그리고 커널 스택은 독립적으로 스케줄링되고 각각 task_struct 를 갖는 프로세스들이기 때문에 따로 갖고 있습니다.

이제 졸업이다...사랑하는 SKKULUG 후배들아 안녕~

toy의 이미지

쓰레드하나마다 task_struct가 만들어지니 커널스택은 따로 갖고있겠지요...
그런데요... 유저모드의 스택은 따로 갖고있어야 하는것 아닌가요?
유저모드 스택도 공유한다는게..좀 이해가 안됩니다.
:oops:
ps.
유저모드에서의 쓰레드에 대해서 질문드립니다...

kkojiband의 이미지

아 그 스택이요...^^;

clone system call 을 호출할때 새로운 thread 를 위한 유저 스택의 포인터값을 지정해줍니다. 그럼 새로 생성된 thread 는 그 스택을 사용하지요. 그리고 그 스택은 당연히 parent process 의 linear address 내에 있는 공간입니다.

이제 졸업이다...사랑하는 SKKULUG 후배들아 안녕~

toy의 이미지

아 그렇군요 ^^ 감사합니다.

원래 프로세스에 있던 스택공간에서 esp값만 살짝 바꿔치기해서 하는 거였군여..
그런데 또 질문이 생기네요... :oops:
그렇다면 만약 너무 많은 thread가 만들어져서 원래있던 쓰레드에 있던 스택공간을 다써버렸다면 어찌될까요....

계속질문만 많아지구..죄송합니당...

pthread라이브러리 소스를 봐야하나..ㅠㅜ

kkojiband의 이미지

하나의 linear address 에서 무한정으로 새로운 thread 의 stack 을 할당할수는 없는거니까 당연히 한계는 있겠죠...

linux 의 pthread library 2.3.2 의 PTHREAD_THREADS_MAX 값은 default 로 16384 개입니다. 이 값은 pthread library 를 컴파일할때 지정해주는걸로 알고 있습니다. 이 값 자체가 stack 의 한계때문에 만들어진 값인지는 저도 정확하지가 않네요. 다른 여러 가지 제한 사항도 있을테니까요...

그리고 pthread library 를 구체적으로 분석해보진 않아서 어떤 식으로 stack 을 관리하는지는 말씀을 드릴수가 없네요...

여기에 대해서는 pthread library 의 내부 구현에 관련된 문서를 참고해보시는게 좋을것같습니다...

그럼 열심히 하세요~ 근데 주말인데도 열심히 하시네요^^

이제 졸업이다...사랑하는 SKKULUG 후배들아 안녕~

toy의 이미지

getpid()가 쓰레드 마다 다른게 아와서 헤메고 있는데...
pthread 버전을 보니..0.9군요... :oops:
아 참 기가막혀서리..ㅠ

toy의 이미지

sys_clone()을 보니..... 항상 새로운 스택을 쓰는것같진 않고...
sys_clone()호출시 새로운 스택을 지정하지 않았을때는 호출한 쓰레드의 스택포인터를 그대로 사용하는듯 하네요..( 확실치는 않음)
결국은 pthread라이브러리 소스를 봐야만 알수있는것같네요...

747 asmlinkage int sys_clone(struct pt_regs regs)
748 {
749 unsigned long clone_flags;
750 unsigned long newsp;
751
752 clone_flags = regs.ebx;
753 newsp = regs.ecx;
754 if (!newsp) <<=========
755 newsp = regs.esp;
756 return do_fork(clone_flags, newsp, &regs, 0);
757 }

혹시 pthread라이브러리 분석(?)해놓은 글은 없겠죠? 흑...

toy의 이미지

(딴곳에 정리하기 귀찮아서 이곳에 끄적입니다.
질답란을 어지럽히는 것 같아 죄송 -.- )

clone()을 사용해보니...2번째 인수인 스택을 안주니까 -1 즉 에러를 리턴하네요.
스택영역을 꼭 지정해줘야되는것같습니다.
pthread lib에서 확인해봐야징..~~~ ^^

advanced의 이미지

pthread 는 대표적인 유저레벨 스레드로 알고 있습니다

유제레벨 스레드의 멀티프로세스 모델은 1:N 형태로

커널 측면에서 보면 실제로는 한개의 스레드지만

한개의 스레드 한에 program count, stack 이나 register, 우선순위 등등을

스레드 별로 따로 관리, text 영역이나 data 영역(전역변수) 등등을 공유하고

유저레벨에서 스케쥴되어 컨택스트 스위칭 되는걸로

알고 있습니다

운영체제 수업시간에 얼핏 들은거는 이와 같구요

이 이상은 자세히는 모르겠네요

- advanced -

toy의 이미지

아...보통 다른 유닉스같은 경우는 그런식으로 구현되었지요... 1:N 으로요..
제가 알기로... 리눅스는 1:1입니다.
리눅스는 쓰레드라고 해봐야 특별한건 아니고요... 자원을 많이 공유하는 프로세스 정도입니다.
저도 잘 모르지만 몇자 적었습니다...

댓글 달기

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