OS教科書對進程和線程的區別有這樣簡單的歸納:進程是資源分配的單位,線程是調度的單位。可是Linux內核是不區分進程和線程的,都用任務(task_struct)來表示,何時叫進程何時叫線程,須要視上下文而定。雖沒有專門的線程實現,但內核用輕量級進程LWP(Light Weight Process)來代替線程。linux
內核比如服務器,用戶任務比如客戶端,內核的一切都是爲用戶態服務的。輕量級進程就是爲了支持用戶態線程庫。服務器
Posix thread是符合posix標準線程庫的統稱,具體實現有多種,在此不贅述,只要知道線程庫的實現按照用戶態線程數和內核進程數的比例可分爲三種模型:N:1, M:N和1:1。執行下面的命令能夠查看你的系統上用的是什麼線程庫:.net
$ getconf GNU_LIBPTHREAD_VERSION NPTL 2.22
NPTL(Native Posix Thread Lib)是Linux的線程實現,用的是1:1模型。這裏有篇文章將的很好,請參考NPTL分析之線程的建立。線程
輕量級進程就是linux所謂的「線程」,它只是共享了父進程不少資源如進程地址空間,文件描述符和信號量等,而獨立的資源只有任務描述符task_struct,內核棧等與調度有關的,作到了:資源共享,調度獨立。code
共享進程地址空間struct task_struct {struct mm_struct *mm;}
是經過讓多個進程的mm
指向同一個虛擬內存struct mm_struct
實現的。經過pthread_create()建立線程時,會經過clone()系統調用傳入各類flags組合來決定哪些資源須要與父進程共享。blog
struct mm_struct
表示了一個進程虛擬地址空間,虛擬地址空間的layout不少參考書都有,struct mm_struct {unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end;}
,代碼,數據,堆,棧,參數,環境變量各段空間都有指向。而這些虛擬內存段與物理內存的映射關係是怎麼創建的呢?答案是經過內存映射mmap。VMA(Virtual Memory Area)列表struct mm_struct {struct vm_area_struct *mmap; /* list of VMAs */}
, 有些vma如動態庫,可執行程序是經過mmap, 有些vma如堆,棧是經過匿名映射完成的。進程
進程描述符裏有個字段struct task_struct { struct list_head thread_group;}
,明顯是想把一個線程組的線程放在一塊兒。進程組struct task_struct { pid_t tgid }
, tgid就是線程組裏領頭進程struct task_struct {struct task_struct *group_leader;}
的pid。內存