İş parçacığı Linux'ta işlemler olarak uygulanır mı?


65

Mark Mitchell, Jeffrey Oldham ve Alex Samuel'in Gelişmiş Linux Programcılığı kitabını okuyorum . 2001'den beri, biraz eski. Ama ben zaten onu oldukça iyi buluyorum.

Ancak Linux'un kabuk çıktısında ürettiğinden farklılaştığı bir noktaya geldim. 92. sayfada (izleyicide 116), 4.5 GNU / Linux Thread Uygulaması bölümü bu cümleyi içeren paragrafla başlamaktadır:

GNIX / Linux'ta POSIX konularının uygulanması, UNIX benzeri diğer birçok sistemde konu uygulamasından önemli ölçüde farklıdır: GNU / Linux'ta, thread'ler süreç olarak uygulanır.

Bu kilit nokta gibi görünüyor ve daha sonra bir C kodu ile gösteriliyor. Kitaptaki çıktı:

main thread pid is 14608
child thread pid is 14610

Ve benim Ubuntu 16.04'ümde:

main thread pid is 3615
child thread pid is 3615

ps çıktı bunu destekler.

Sanırım 2001 ile şimdi arasında bir şey değişmiş olmalı.

Bir sonraki sayfadaki bir sonraki alt bölüm, 4.5.1 Sinyal İşleme, önceki ifadeye dayanmaktadır:

Sinyaller ve iplikler arasındaki etkileşimin davranışı bir UNIX benzeri sistemden diğerine değişmektedir. GNU / Linux'ta, davranış, iş parçacıklarının süreçler halinde uygulanması gerçeğiyle belirlenir.

Ve daha sonra kitapta bunun daha da önemli olacağı görülüyor. Biri burada neler olduğunu açıklayabilir mi?

Bunu gördüm Gördüm Linux çekirdeği konuları gerçekten çekirdek işlemleri? , ama pek yardımcı olmuyor. Kafam karıştı.

Bu C kodudur:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* thread_function (void* arg)
{
    fprintf (stderr, "child thread pid is %d\n", (int) getpid ());
    /* Spin forever. */
    while (1);
    return NULL;
}

int main ()
{
    pthread_t thread;
    fprintf (stderr, "main thread pid is %d\n", (int) getpid ());
    pthread_create (&thread, NULL, &thread_function, NULL);
    /* Spin forever. */
    while (1);
    return 0;
}

1
Kafanızın kaynağının ne olduğunu anlamadım. Konular, adres alanını ebeveynleriyle paylaşan süreçler olarak uygulanır.
Johan Myréen

2
@ JohanMyréen Öyleyse neden diş iplikleri eşit?
Tomasz

Ah, şimdi anlıyorum. Evet, gerçekten bir şey değişti. @ İlkkachu'nun cevabına bakınız.
Johan Myréen

5
İş parçacığı hala işlemler olarak uygulanır - ancak şimdi getpidbir iş parçacığı grubu kimliği olarak adlandırılacak olanı ve kullanmanız gereken bir işlem için benzersiz bir kimlik elde etmek için döndürür gettid. Ancak, çekirdek dışındaki çoğu kişi ve araç, bir iş parçacığı grubuna bir işlem diyecek ve diğer sistemlerle tutarlılık için bir işlem iş parçacığı arayacak.
kullanıcı253751,

Pek sayılmaz. Bir process bunu yaparken olacağını, bir iş parçacığı asla denir, kendi hafıza ve dosya tanımlayıcı açmış de diğer sistemlerle tutarlı.
reinierpost

Yanıtlar:


50

Bence clone(2)man sayfasının bu kısmı yeniden farkı temizleyebilir. PID:

CLONE_THREAD (Linux 2.4.0-test8’den beri)
CLONE_THREAD ayarlanmışsa, çocuk arama işlemi ile aynı konu grubuna yerleştirilir.
İş parçacığı grupları, tek bir PID'yi paylaşan bir iş parçacığı POSIX iş parçacığı kavramını desteklemek için Linux 2.4'te eklenen bir özellikti. Dahili olarak, bu paylaşılan PID, konu grubu için sözde konu grubu tanımlayıcısıdır (TGID). Linux 2.4'ten beri, getpid (2) çağrıları arayanın TGID'sini döndürür.

"İş parçacığı işlem olarak uygulanır" ifadesi, geçmişte ayrı PID'lere sahip iş parçacıkları meselesini belirtir. Temel olarak, Linux aslında bir süreç içinde iş parçacığına sahip değildi, sadece sanal bellek ya da dosya tanımlayıcıları gibi paylaşılan kaynaklara sahip olabilecek ayrı işlemleri (ayrı PID'lerle) içeriyordu. CLONE_THREADişlem kimliğinin (*) ve iş parçacığı kimliğinin ayrılması , Linux davranışını diğer sistemlere ve bu anlamda POSIX gereksinimlerine daha çok benzetmektedir. Her ne kadar teknik olarak işletim sistemi hala iş parçacıkları ve işlemler için ayrı uygulamalara sahip değil.

Sinyal işleme bu daha ayrıntılı olarak anlatılmıştır, eski uygulanmasıyla başka sorunlu bölgesi olan kağıt anlamına gelir @FooF Yanıtlarında .

Yorumlarda belirtildiği gibi, Linux 2.4, aynı kitapla aynı yıl, 2001'de de yayımlandı, bu yüzden haberlerin bu baskıya ulaşmaması şaşırtıcı değildi.


2
sanal bellek veya dosya tanımlayıcıları gibi paylaşılan kaynaklara sahip olabilecek ayrı işlemler. Bu hala Linux iş parçacıklarının nasıl çalıştığını, sizin de bahsettiğiniz konuların temizlendiğini söyleyerek devam ediyor. Çekirdeğin "thread" veya "process" te kullanılan programlama birimlerini çağırmanın gerçekten alakasız olduğunu söyleyebilirim. Linux'ta sadece "süreçler" olarak adlandırılmaları, şimdi oldukları tek şey anlamına gelmez.
Andrew Henle

@AndrewHenle, evet, biraz düzenledi. Umarım ifade ile zor bir zaman gibi görünse de, bu senin düşünceni yakalar. (bir ileri gidin ve isterseniz bu bölümü düzenleyin.) Diğer Unix benzeri işletim sistemlerinde, işlemcilerin işlemlere karşı daha belirgin bir ayrımının olduğunu anladım. her iki fonksiyon da. Ancak diğer sistemler hakkında yeterince bilgim yok ve kaynakları elimde değil, bu yüzden somut bir şey söylemek zor.
ilkkachu

@tomas Bu cevabın Linux'un şimdi nasıl çalıştığını açıkladığını unutmayın. İlkkachu’nın ima ettiği gibi, kitap yazıldığında farklı şekilde çalıştı. FooF'un cevabı Linux'un o zaman nasıl çalıştığını açıklıyor.
Gilles,

38

Haklısın, gerçekten de "2001 ile şimdi arasında bir şey değişmiş olmalı". Okuduğunuz kitap dünyayı Linux'taki POSIX konularının LinuxThreads adlı ilk tarihsel uygulamasına göre açıklar ( bazıları için ayrıca Wikipedia makalesine bakın).

LinuxThreads POSIX standardında bazı uyumluluk sorunları yaşadı - örneğin PID'leri paylaşmayan konular - ve diğer ciddi problemler. Bu kusurları gidermek için, NPTL (Native POSIX Thread Library) adlı başka bir uygulama daha iyi POSIX uyumluluğuna ulaşmak için gerekli çekirdek ve kullanıcı alanı kütüphanesi desteğini eklemek için Red Hat tarafından öncülük edildi (IBM tarafından NGPT (" Gelecek Nesil Posix Konuları "), NPTL'deki Wikipedia makalesine bakın ). Eklenen ek bayrakları clone(2)(özellikle sistem çağrısı içinde işaret onun cevabını ) muhtemelen çekirdek değişikliklerin en belirgin parçasıdır. Çalışmanın kullanıcı alanı, sonunda GNU C Kütüphanesine dahil edildi.CLONE_THREAD@ikkkachu

Bugünlerde bazı gömülü Linux SDK'ları eski LinuxThreads uygulamasını kullanıyorlar çünkü uClibc (ayrıca CClibc de denir) adlı LibC'nin daha küçük bellek ayak izi sürümünü kullanıyorlar ve GNU LibC'den NPTL kullanıcı alanı uygulamasının taşınması ve kabul edilmesinin dikkate alınması uzun yıllar aldı . varsayılan POSIX iş parçacığı uygulaması, bu özel platformlar genel olarak konuşursak, yıldırım hızıyla en yeni modaları takip etmeye çabalamıyor. Bu, bu platformlardaki farklı iş parçacıkları için PID'lerin POSIX standardının belirttiğinin aksine - tıpkı okuduğunuz kitabın tarif ettiği gibi - farklı olduğunun farkına varmak suretiyle gözlemlenebilir. Aslında bir kez aradınpthread_create(), birdenbire bir araya gelmek için ek işlem gerektiğinden işlem sayımını birden üçe çıkardınız.

Linux pthreads (7) kılavuz sayfası, ikisi arasındaki farklara dair kapsamlı ve ilginç bir genel bakış sunar. Başka aydınlatıcı olsa dışarı güncel, farklılıkların açıklaması şudur kağıt NPTL tasarımı hakkında Ulrich depper ve Ingo Molnar tarafından.

Kitabın bu bölümünü çok ciddiye almamanızı tavsiye ederim. Bunun yerine Butenhof'un Programlama POSIX konularını ve konu hakkında POSIX ve Linux kılavuz sayfalarını tavsiye ederim. Konuyla ilgili birçok ders yanlış.


22

(Userspace) thread'leri Linux'ta olduğu gibi süreçler olarak uygulanmaz, kendi özel adres alanlarına sahip olmadıkları için yine de ana sürecin adres alanını paylaşırlar.

Ancak, bu iş parçacıkları çekirdek işlem muhasebe sistemini kullanmak için uygulanır, bu yüzden kendi iş parçacığı kimliklerini (TID) ayırırlar, ancak ana işlemle aynı PID ve 'iş parçacığı grup kimliği' (TGID) verilir. yeni bir TGID ve PID'nin oluşturulduğu bir çatal ve TID, PID ile aynıdır.

Öyleyse, son çekirdeğin sorgulanabilecek ayrı bir TID'ye sahip olduğu anlaşılıyor, bu durum iş parçacıkları için farklı, yukarıdaki main () thread_function () öğesinde bunu göstermek için uygun bir kod pasajı:

    long tid = syscall(SYS_gettid);
    printf("%ld\n", tid);

Yani bununla bütün kod şöyle olacaktır:

#include <pthread.h>                                                                                                                                          
#include <stdio.h>                                                                                                                                            
#include <unistd.h>                                                                                                                                           
#include <syscall.h>                                                                                                                                          

void* thread_function (void* arg)                                                                                                                             
{                                                                                                                                                             
    long tid = syscall(SYS_gettid);                                                                                                                           
    printf("child thread TID is %ld\n", tid);                                                                                                                 
    fprintf (stderr, "child thread pid is %d\n", (int) getpid ());                                                                                            
    /* Spin forever. */                                                                                                                                       
    while (1);                                                                                                                                                
    return NULL;                                                                                                                                              
}                                                                                                                                                             

int main ()                                                                                                                                                   
{                                                                                                                                               
    pthread_t thread;                                                                               
    long tid = syscall(SYS_gettid);     
    printf("main TID is %ld\n", tid);                                                                                             
    fprintf (stderr, "main thread pid is %d\n", (int) getpid ());                                                    
    pthread_create (&thread, NULL, &thread_function, NULL);                                           
    /* Spin forever. */                                                                                                                                       
    while (1);                                                                                                                                                
    return 0;                                                                                                                                                 
} 

Örnek çıktı verilmesi:

main TID is 17963
main thread pid is 17963
thread TID is 17964
child thread pid is 17963

3
@tomas einonm haklı. Kitabın söylediklerini göz ardı et, çok kafa karıştırıcı. Dunno hangi fikir yazarının iletmek istediğini biliyordu, ama çok kötü bir şekilde başarısız oldu. Öyleyse, Linux'ta Çekirdek iş parçacıklarına ve Kullanıcı alanı iş parçacıklarına sahipsiniz. Çekirdek iş parçacıkları, esasen kullanıcı alanı olmayan süreçlerdir. Kullanıcı alanı konuları normal POSIX konularıdır. Kullanıcı alanı işlemleri dosya tanımlayıcılarını paylaşabilir, kod bölümlerini paylaşabilir, ancak tamamen ayrı Sanal Adres Alanlarında yaşayabilir. Bir işlem içindeki kullanıcı alanı iş parçacıkları kod bölümünü, statik belleği ve öbekleri (dinamik bellek) paylaşır, ancak ayrı işlemci kayıt kümeleri ve yığınlarına sahiptir.
Boris Burkov

8

Temel olarak, kitabınızdaki bilgiler, Linux'ta konuların utanç verici derecede kötü bir şekilde uygulanmasından dolayı tarihsel olarak doğrudur. SO ile ilgili olarak bu soruya cevabım, sorunuza bir cevap olarak da hizmet eder:

https://stackoverflow.com/questions/9154671/distinction-between-processes-and-threads-in-linux/9154725#9154725

Bu kafa karışıklıklarının tümü, çekirdek geliştiricilerin başlangıçta, çekirdek ve bellek tanımlayıcılarını paylaşmalarını sağlayacak bir yöntem sunduğu sürece, çekirdeklerin ilkel olarak çekirdek işlemleri kullanarak neredeyse tamamen kullanıcı alanında uygulanabileceği mantıksız ve yanlış bir görüşe sahip olmalarından kaynaklanmaktadır. . Bu, kötü bilinen kötü LinuxThreads POSIX konularının uygulanmasına yol açıyordu, bu oldukça yanlış bir isimdi çünkü POSIX iş parçacığı anlambilimine uzaktan benzeyen bir şey vermedi. Sonunda LinuxThreads (NPTL ile) değiştirildi, ancak kafa karıştırıcı terminoloji ve yanlış anlamalar hala devam ediyor.

Gerçekleştirilmesi gereken ilk ve en önemli şey "PID" nin çekirdek alanı ve kullanıcı alanı içindeki farklı anlamlara gelmesidir. Çekirdeğin adlandırdığı PID'ler aslında, pthread_tayrı bir tanımlayıcı olan, karıştırılmaması gereken, çekirdek düzeyinde iş parçacığı kimlikleridir (genellikle TID'ler olarak adlandırılır) . Sistemdeki her bir iş parçacığının, aynı işlemde veya farklı bir durumda, çekirdek terminolojisinde benzersiz bir TID (veya "PID") vardır.

POSIX'te "işlem" anlamında PID olarak kabul edilen, diğer taraftan, çekirdekte "iş parçacığı grubu kimliği" veya "TGID" olarak adlandırılır. Her işlem, her biri kendi TID'sine (çekirdek PID) sahip olan bir veya daha fazla dişten (çekirdek işlemleri) oluşur, ancak tümü, içinde mainçalışan ilk ipliğin TID'sine (çekirdek PID) eşit olan aynı TGID'yi paylaşır .

Ne zaman topsize konuları gösterir, bu Tıd'ler (çekirdek PID'ler) değil, PID'ler (çekirdek TGIDs) gösteriyor ve her iş parçacığı ayrı birine sahiptir bu yüzden.

NPTL'nin ortaya çıkmasıyla, PID argümanı alan veya çağıran süreçte hareket eden çoğu sistem çağrısı , PID'yi bir TGID olarak ele almak ve tüm "iş parçacığı grubu" (POSIX işlemi) üzerinde çalışmak üzere değiştirildi.


8

Dahili olarak, linux çekirdeğinde süreçler veya iplikler gibi bir şey yoktur. İşlemler ve iş parçacıkları çoğunlukla bir kullanıcı alanı kavramıdır, çekirdeğin kendisi yalnızca kaynaklarını hiçbirini, bir kısmını ya da tamamını başka görevlerle paylaşamayan, parçalanabilen bir nesne olan "görevleri" görür. İş parçacıkları, kaynaklarının çoğunu (adres alanı, mmapler, borular, açık dosya işleyicileri, soketler vb.) Üst görevle paylaşacak şekilde yapılandırılmış görevlerdir ve işlemler, üst görevle en az kaynakları paylaşacak şekilde yapılandırılmış görevlerdir .

Doğrudan Linux API'yi kullandığınızda ( clone () , fork () ve pthread_create () yerine ), o zaman ne kadar kaynak paylaşacağınızı veya paylaşmayacağınızı tanımlama konusunda daha fazla esnekliğe sahip olursunuz. işlemek ya da tamamen bir iş parçacığı. Bu düşük düzeyli çağrıları doğrudan kullanırsanız, oluşturmak için tüm kaynaklarını gerçekten ana görevle veya tam tersi olarak paylaşan yeni bir TGID ile (dolayısıyla çoğu kullanıcı aracı tarafından bir işlem olarak kabul edilir) bir görev oluşturmak da mümkündür. paylaşılan TGID'ye sahip bir görev (bu nedenle çoğu kullanıcı aracı tarafından iş parçacığı olarak kabul edilir), üst görevi ile kaynak paylaşmayan bir görevdir.

Linux 2.4 TGID'yi uygularken, bu sadece kaynak muhasebesi yararınadır. Birçok kullanıcı ve kullanıcı alanı aracı, ilgili görevleri birlikte gruplayabilmeyi ve kaynak kullanımını birlikte bildirebilmeyi yararlı bulmaktadır.

Linux'ta görevlerin uygulanması, kullanıcı araçları tarafından sunulan dünya görüşü süreçlerinden ve konularından çok daha akıcıdır.


Kağıt Okuduktan sonra, gerçekten söyleyemem böylece bağlantılı @FooF çekirdek süreçleri ve konuları ayrı varlıklar olarak (örneğin sinyal işleme ve exec ()) dikkate sahiptir puan sayısını açıklar, böyle var" Linux çekirdeğindeki süreçler ya da iplikler gibi bir şey
ilkkachu

5

Linus Torvalds, bir çekirdek posta listesinde 1996 yılında "hem iş parçacıklarının hem de işlemlerin," sadece bu CoE'nin bütünlüğünün bir holdingi olan "yürütme bağlamı olarak değerlendirildiğini" belirtti. durum, MMU durumu, izinler ve çeşitli iletişim durumları (açık dosyalar, sinyal işleyicileri vb.) ".

// simple program to create threads that simply sleep
// compile in debian jessie with apt-get install build-essential
// and then g++ -O4 -Wall -std=c++0x -pthread threads2.cpp -o threads2
#include <string>
#include <iostream>
#include <thread>
#include <chrono>

// how many seconds will the threads sleep for?
#define SLEEPTIME 100
// how many threads should I start?
#define NUM_THREADS 25

using namespace std;

// The function we want to execute on the new thread.
void threadSleeper(int threadid){
    // output what number thread we've created
    cout << "task: " << threadid << "\n";
    // take a nap and sleep for a while
    std::this_thread::sleep_for(std::chrono::seconds(SLEEPTIME));
}

void main(){
    // create an array of thread handles
    thread threadArr[NUM_THREADS];
    for(int i=0;i<NUM_THREADS;i++){
        // spawn the threads
        threadArr[i]=thread(threadSleeper, i);
    }
    for(int i=0;i<NUM_THREADS;i++){
        // wait for the threads to finish
        threadArr[i].join();
    }
    // program done
    cout << "Done\n";
    return;
}

Gördüğünüz gibi, bu program bir kerede 25 iş parçacığı doğuracak, her biri 100 saniye uyuyacak ve daha sonra ana programa tekrar katılacak. 25 iş parçacığının tamamı programa tekrar katıldıktan sonra program yapılır ve programdan çıkar.

Kullanarak top"thread2" programının 25 örneğini görebilirsiniz. Ama çocuk sıkıcı. Çıkışı ps auwxdaha da ilginç ... AMA ps -eLfbiraz heyecanlı hale geliyor.

UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
debian     689   687   689  0    1 14:52 ?        00:00:00 sshd: debian@pts/0  
debian     690   689   690  0    1 14:52 pts/0    00:00:00 -bash
debian    6217   690  6217  0    1 15:04 pts/0    00:00:00 screen
debian    6218  6217  6218  0    1 15:04 ?        00:00:00 SCREEN
debian    6219  6218  6219  0    1 15:04 pts/1    00:00:00 /bin/bash
debian    6226  6218  6226  0    1 15:04 pts/2    00:00:00 /bin/bash
debian    6232  6219  6232  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6233  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6234  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6235  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6236  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6237  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6238  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6239  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6240  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6241  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6242  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6243  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6244  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6245  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6246  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6247  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6248  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6249  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6250  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6251  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6252  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6253  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6254  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6255  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6256  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6232  6219  6257  0   26 15:04 pts/1    00:00:00 ./threads2
debian    6260  6226  6260  0    1 15:04 pts/2    00:00:00 ps -eLf

thread2Programın oluşturduğu tüm 26 CoE'yi burada görebilirsiniz . Hepsi aynı işlem kimliğini (PID) ve ana işlem kimliğini (PPID) paylaşır, ancak her birinin farklı bir LWP kimliği (hafif işlem) vardır ve LWP'lerin (NLWP) sayısı 26 CoE olduğunu gösterir - ana program ve 25 konu doğdu.


Doğru, bir iplik sadece hafif bir işlemdir (LWP)
fpmurphy

3

Linux süreçleri ve iş parçacığı geldiğinde vardır tür aynı şey. Hangisi aynı sistem çağrısı ile oluşturulan söylemek: clone.

Bunu düşünürseniz, iş parçacığı ve işlemler arasındaki fark, çekirdek nesnelerinin çocuk ve ebeveyn tarafından paylaşılacağıdır. İşlemler için çok fazla bir şey yok: açık dosya tanımlayıcıları, daha önce yazılmayan bellek bölümleri, muhtemelen başımın üstünde düşünemediğim birkaç kişi. Konu için, çok daha fazla nesne paylaşılıyor, ancak hepsi paylaşılmıyor.

Linux'ta konu ve nesneleri daha da yaklaştıran şey unsharesistem çağrısıdır. Paylaşılmaya başlanan çekirdek nesneleri, iş parçacığı oluşturulduktan sonra paylaşılmayabilir. Örneğin, aynı işlemin farklı dosya tanımlayıcı alanına sahip iki iş parçacığına sahip olabilirsiniz (iş parçacığı oluşturulduktan sonra dosya tanımlayıcılarının paylaşımını iptal ederek). Bir iş parçacığı oluşturarak, unshareher iki iş parçacığını arayarak ve sonra tüm dosyaları kapatarak ve her iki iş parçacığında yeni dosyalar, borular ya da nesneler açarak kendiniz test edebilirsiniz . Ardından /proc/your_proc_fd/task/*/fdiçeriye bakın ve her birinin task(iş parçacığı olarak oluşturduğunuz) farklı fd'lere sahip olacağını göreceksiniz.

Aslında, hem yeni iş parçacıklarının hem de yeni işlemlerin yaratılması, clonealtında çağrı yapan ve yeni oluşturulan işlem-iş parçacığı-thingamajig'in (yani task) çağrı çeken işlem / iş parçacığı ile paylaşacağını belirten çekirdek nesnelerden hangisini tanımladığını belirten kütüphane rutinleridir .

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.