İş parçacıkları aynı PID'yi paylaşıyorsa, nasıl tanımlanabilirler?


101

İş parçacığının Linux'ta uygulanmasıyla ilgili bir sorgum var.

Linux, açık bir iş parçacığı desteğine sahip değildir. Kullanıcı alanında, evreler oluşturmak için bir iş parçacığı kitaplığı (NPTL gibi) kullanabiliriz. Şimdi NPTL kullanırsak, 1: 1 eşlemeyi destekler.

Çekirdek, evreleri clone()uygulamak için işlevi kullanacaktır .

4 iş parçacığı oluşturduğumu varsayalım. O zaman şu anlama gelir:

  • 4 olacak task_struct.
  • İçinde, task_structklonlanacak argümanlara göre kaynakların paylaşılması sağlanacaktır (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND).

Şimdi şu sorguya sahibim:

  1. 4 iş parçacığı aynı PID'ye sahip olacak mı? Birisi detaylandırabilirse, PID'lerin nasıl paylaşıldığı.
  2. Farklı konular nasıl belirlenir; bazı TID (iş parçacığı kimliği) kavramı var mı?

Yanıtlar:


280

Dört iş parçacığı aynı PID'ye sahip olacaktır, ancak yalnızca yukarıdan bakıldığında . Ne sen (bir kullanıcı olarak) bir PID çağrı çekirdek (alttan bakarak) bir PID dediği değil.

In kernel, her iplik iplik PID (muhtemelen bu TID veya iplik kimliğini aramaya daha mantıklı olsa da) ve onlar da bir TGID (iplik grubu kimliğini) sahip bir PID denen o kendi kimliği var bu tüm süreci başlattı.

Basit bir şekilde, yeni bir işlem oluşturulduğunda, hem PID hem de TGID'nin aynı (yeni) sayı olduğu bir iş parçacığı olarak görünür.

Bir iş parçacığı başka başladığında iplik, yani başlatan iplik kendi PID alır (zamanlayıcı bağımsız olarak planı yapsın) ama orijinal iplikle TGID devralır.

Bu şekilde, süreçler (iş parçacığı grubu kimlikleri) size bildirilirken, çekirdek hangi sürece ait olduklarından bağımsız olarak iş parçacıklarını mutlu bir şekilde planlayabilir.

Aşağıdaki iş parçacığı hiyerarşisi yardımcı olabilir (a) :

                      USER VIEW
 <-- PID 43 --> <----------------- PID 42 ----------------->
                     +---------+
                     | process |
                    _| pid=42  |_
                  _/ | tgid=42 | \_ (new thread) _
       _ (fork) _/   +---------+                  \
      /                                        +---------+
+---------+                                    | process |
| process |                                    | pid=44  |
| pid=43  |                                    | tgid=42 |
| tgid=43 |                                    +---------+
+---------+
 <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
                     KERNEL VIEW

Yeni bir işlem başlatmanın (solda) size yeni bir PID ve yeni bir TGID (her ikisi de aynı değere ayarlanmış) verirken, yeni bir iş parçacığı başlatmanın (sağda) aynı kalırken size yeni bir PID verdiğini görebilirsiniz. Onu başlatan iş parçacığı olarak TGID.


(a) Etkileyici grafik becerilerime hayranlıkla titreyin :-)


20
Bilginize, getpid()tgid döndürür: www.makelinux.com/asmlinkage long sys_getpid(void) { return current->tgid;}
Duke

6
@Duke - wow, bu yüzden bir gettgid(2)işlev bulamadım . Ve getpid()TID'yi (iş parçacığının "PID" si) geri döndürmeyecek ve nereden girdiği var gettid(2). Bu şekilde, ana iş parçacığında olup olmadığımızı söyleyebilirim.
Tomasz Gandor

2
Bu, başka bir ilginç noktaya yol açar: Yani, eğer evreler ve süreçler çekirdek içinde eşit olarak işlenirse (tgid dışında), sonuçta çok evreli bir süreç tek iş parçacıklı bir süreçten daha fazla CPU süresi elde eder, her ikisinin de aynı olması şartıyla öncelik ve hiçbir iş parçacığı herhangi bir nedenle durdurulmaz (bir muteks beklemek gibi).
Aconcagua

1
@Aconcagua, CFS (Linux'ta tamamen adil zamanlayıcı) genellikle bu şekilde çalışır, ancak aynı zamanda adaletin bireysel görevler yerine belirli görev gruplarında işlemesini sağlamak için grup zamanlayıcı uzantılarının kullanılmasına da izin verir. Üstünü bir bakıştan başka hiç incelemedim.
paxdiablo

grup kimliğini almak için '' getpgrp ''
Pengcheng

2

Dişler, PID'ler ve TGID (Diş grubu kimliği) kullanılarak tanımlanır. Ayrıca, hangi iş parçacığının, temelde bir sürecin PID'sini başlattığı herhangi bir iş parçacığı ile paylaşan ebeveyn olduğunu da bilirler. İş parçacığı kimlikleri genellikle iş parçacığı kitaplığının kendisi tarafından yönetilir (pthread vb. 4 iş parçacığı başlatılırsa, aynı PID'ye sahip olmaları gerekir. Çekirdeğin kendisi iş parçacığı zamanlamasını ve benzerlerini idare edecektir, ancak kitaplık evreleri yönetecek olandır (evre birleştirme ve bekleme yöntemlerini kullanmanıza bağlı olarak çalışıp çalışmayabilirler).

Not: Bu benim hatırladığım çekirdek 2.6.36'dan. Mevcut çekirdek sürümlerindeki çalışmam G / Ç katmanında olduğundan o zamandan beri bunun değişip değişmediğini bilmiyorum.


İşte Linux 2.4 için yararlı bulabileceğiniz bir açıklama unix.stackexchange.com/a/364663/387462
sindhu_sp

-6

Linux, fork()sistem çağrısına bir işlemi kopyalamanın geleneksel işlevselliğini sağlar. Linux ayrıca clone()sistem çağrısını kullanarak evreler oluşturma yeteneği de sağlar. Ancak, linux süreçler ve iş parçacığı arasında ayrım yapmaz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.