C語言編程中pid, tid以及真實pid的關係

來源:互聯網
上載者:User

標籤:libc   資料區段   else   inherits   有一個   技術分享   ace   def   方法   

對於ubuntu14.04作業系統,可以在/usr/src/linux-headers-4.4.0-31/include/linux/sched.h檔案中看到進程式控制制塊的結構體,如下

struct task_struct {        volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */        void *stack;        atomic_t usage;        unsigned int flags;     /* per process flags, defined below */        unsigned int ptrace;#ifdef CONFIG_SMP        struct llist_node wake_entry;        int on_cpu;        unsigned int wakee_flips;        unsigned long wakee_flip_decay_ts;        struct task_struct *last_wakee;        int wake_cpu;#endif        ......        ......        pid_t pid;        pid_t tgid;        ......        ......}

可以看到,裡面定義了兩個欄位,pid和tgid,其中pid就是這個輕量級進程lwp的id,而tgid是lwp組的id,即主lwp的id

 

原文:http://blog.csdn.net/u012398613/article/details/52183708

1、pid,tid,真實pid的使用
進程pid: getpid()                 線程tid: pthread_self()     //進程內唯一,但是在不同進程則不唯一。線程pid: syscall(SYS_gettid)     //系統內是唯一的#include <stdio.h>#include <pthread.h>#include <sys/types.h>#include <sys/syscall.h>struct message{    int i;    int j;};void *hello(struct message *str){    printf("child, the tid=%lu, pid=%d\n",pthread_self(),syscall(SYS_gettid));    printf("the arg.i is %d, arg.j is %d\n",str->i,str->j);    printf("child, getpid()=%d\n",getpid());    while(1);}int main(int argc, char *argv[]){    struct message test;    pthread_t thread_id;    test.i=10;    test.j=20;    pthread_create(&thread_id,NULL,hello,&test);    printf("parent, the tid=%lu, pid=%d\n",pthread_self(),syscall(SYS_gettid));    printf("parent, getpid()=%d\n",getpid());    pthread_join(thread_id,NULL);    return 0;}

getpid()得到的是進程的pid,在核心中,每個線程都有自己的PID,要得到線程的PID,必須用syscall(SYS_gettid);

pthread_self函數擷取的是線程ID,線程ID在某進程中是唯一的,在不同的進程中建立的線程可能出現ID值相同的情況。

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <unistd.h>#include <sys/syscall.h>void *thread_one(){    printf("thread_one:int %d main process, the tid=%lu,pid=%ld\n",getpid(),pthread_self(),syscall(SYS_gettid));}void *thread_two(){    printf("thread two:int %d main process, the tid=%lu,pid=%ld\n",getpid(),pthread_self(),syscall(SYS_gettid));}int main(int argc, char *argv[]){    pid_t pid;    pthread_t tid_one,tid_two;    if((pid=fork())==-1)    {        perror("fork");        exit(EXIT_FAILURE);    }    else if(pid==0)    {        pthread_create(&tid_one,NULL,(void *)thread_one,NULL);        pthread_join(tid_one,NULL);    }    else    {        pthread_create(&tid_two,NULL,(void *)thread_two,NULL);        pthread_join(tid_two,NULL);    }    wait(NULL);    return 0;}

2、pid與tid的用途

Linux中,每個進程有一個pid,類型pid_t,由getpid()取得。Linux下的POSIX線程也有一個id,類型pthread_t,由pthread_self()取得,該id由線程維護,其id空間是各個進程獨立的(即不同進程中的線程可能有相同的id)。你可能知道,Linux中的POSIX線程庫實現的線程其實也是一個進程(LWP),只是該進程與主進程(啟動線程的進程)共用一些資源而已,比如程式碼片段,資料區段等。
  有時候我們可能需要知道線程的真實pid。比如進程P1要向另外一個進程P2中的某個線程發送訊號時,既不能使用P2的pid,更不能使用線程的pthread id,而只能使用該線程的真實pid,稱為tid。
  有一個函數gettid()可以得到tid,但glibc並沒有實現該函數,只能通過Linux的系統調用syscall來擷取。使用syscall得到tid只需一行代碼,但為了加深各位看官的印象,簡單提供下面情境。
  有一簇進程,其中一個進程中另外啟了一個線程。各進程共用一個資料結構,由shared_ptr指明,其中儲存有線程的tid。在各個進程的執行過程中,需要判斷線程是否存在,若不存在則(重新)建立。
  首先,線上程函數的開始,需要將自己的tid儲存至共用記憶體,

點擊(此處)摺疊或開啟

  1. #include <sys/syscall.h>
  2. #include <sys/types.h>
  3. void*
  4. thread_func(void *args)
  5. {
  6.     //~ lock shared memory
  7.     shared_ptr->tid = syscall(SYS_gettid); //~ gettid()
  8.     //~ unlock shared memory
  9.     //~ other stuff
  10. }
  在各進程中判斷進程是否存在,

點擊(此處)摺疊或開啟

  1. //~ lock shared memory
  2. pthread_t id;
  3. if (shared_ptr->tid == 0) { //~ tid is initialized to 0
  4.     pthread_create(&id, NULL, thread_func, NULL);
  5. } else if (shared_ptr->tid > 0) {
  6.     int ret = kill(shared_ptr->tid, 0); //~ send signal 0 to thread
  7.     if (ret != 0) { //~ thread already died
  8.         pthread_create(&id, NULL, thread_func, NULL);
  9.     }
  10. }
  11. //~ unlock shared memory
3、linux 系統中查看pid,tid的方法

線程進程都會有自己的ID,從作業系統來講,這個ID就叫做PID

 

 

引用原文

The four threads will have the same PID but only when viewed from above. What you (as a user) call a PID is not what the kernel (looking from below) calls a PID.In the kernel, each thread has it‘s own ID, called a PID (although it would possibly make more sense to call this a TID, or thread ID) and they also have a TGID (thread group ID) which is the PID of the thread that started the whole process.Simplistically, when a new process is created, it appears as a thread where both the PID and TGID are the same (new) number.When a thread starts another thread, that started thread gets its own PID (so the scheduler can schedule it independently) but it inherits the TGID from the original thread.That way, the kernel can happily schedule threads independent of what process they belong to, while processes (thread group IDs) are reported to you.

關於線程繼承關係圖如下:

              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

在這裡你可以清晰的看到,建立一個新的進程會給一個新的PID和TGID,並且2個值相同,
當建立一個新的線程的時候,會給你一個新的PID,並且TGID和之前開始的進程一致。

Linux通過進程查看線程的方法 1).htop按t(顯示進程線程嵌套關係)和H(顯示線程) ,然後F4過濾進程名。2).ps -eLf | grep java(快照,帶線程命令,e是顯示全部進程,L是顯示線程,f全格式輸出) 3).pstree -p <pid>(顯示進程樹,不加pid顯示所有) 4).top -Hp <pid> (即時) 5).ps -T -p <pid>(快照)推薦程度按數字從小到大。

C語言編程中pid, tid以及真實pid的關係

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.