C語言編程中pid, tid以及真實pid的關系(轉)


add by zhj: 下面是我對pid,tgid,ppid的個人理解

對於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是輕量級進程組的id,當創建進程時,我們可以為自己指定

進程的tgid字段,貌似可以隨便指定,只要存在就行,另外在父進程中,可以為子進程設置進程組id,如果沒有指定,它會繼承父進程的進程組id。

還有一個概念ppid,我沒在這個結構體中找到,但操作系統肯定是會記錄的,在Python中,通過os.get_ppid()就可以獲取當前進程的父進程。tgid與ppid,

這兩者其實沒有任何關系,因為tgid是可以自己來指定的,平時基本不用,不用管它。

 

 

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

1、pid,tid,真實pid的使用

進程pid: getpid()                // 相當於os.getpid() 
線程tid: pthread_self()          //進程內唯一,但是在不同進程則不唯一。相當於thread.get_ident()
線程pid: syscall(SYS_gettid)     //系統內是唯一的。python中沒有現成的方法,需要手動調用動態鏈接庫ctypes.CDLL('libc.so.6').syscall(xx)

#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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM