zoukankan      html  css  js  c++  java
  • 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
    ",pthread_self(),syscall(SYS_gettid));
        printf("the arg.i is %d, arg.j is %d
    ",str->i,str->j);
        printf("child, getpid()=%d
    ",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
    ",pthread_self(),syscall(SYS_gettid));
        printf("parent, getpid()=%d
    ",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
    ",getpid(),pthread_self(),syscall(SYS_gettid));
    }
    
    void *thread_two()
    {
        printf("thread two:int %d main process, the tid=%lu,pid=%ld
    ",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

     

  • 相关阅读:
    一些tcp通讯代码
    使用资源监控工具 glances
    命令行方式运行yii2程序
    php获取apk信息
    Yii2简单纪要
    LuCI探究(转)
    proguard混淆jar文件
    hibernate-search-5.1.1简易使用
    数据库应用-java+sqlserver(六)MyFrame
    数据库应用-java+sqlserver(五)ModifyPassword
  • 原文地址:https://www.cnblogs.com/ajianbeyourself/p/8146449.html
Copyright © 2011-2022 走看看