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();
} int main(int argc, char *argv[])
{
struct message test;
pthread_t thread_id;
test.i=;
test.j=;
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 ;
}

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())==-)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if(pid==)
{
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 ;
}

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

C语言编程中pid, tid以及真实pid的关系(转)的更多相关文章

  1. [C] 在 C 语言编程中实现动态数组对象

    对于习惯使用高级语言编程的人来说,使用 C 语言编程最头痛的问题之一就是在使用数组需要事先确定数组长度. C 语言本身不提供动态数组这种数据结构,本文将演示如何在 C 语言编程中实现一种对象来作为动态 ...

  2. R语言编程中的常见错误

    R语言编程中的常见错误有一些错误是R的初学者和经验丰富的R程序员都可能常犯的.如果程序出错了,请检查以下几方面. 使用了错误的大小写.help().Help()和HELP()是三个不同的函数(只有第 ...

  3. Linux 编程中的API函数和系统调用的关系【转】

    转自:http://blog.chinaunix.net/uid-25968088-id-3426027.html 原文地址:Linux 编程中的API函数和系统调用的关系 作者:up哥小号 API: ...

  4. Linux下C语言编程中库的使用

    零.问题 1. 为什么要用到库? 2. 我要用一个库,但是,尼玛命令行上该怎么写呢?或者说库文件如何使用? 3. Linux的库在那些地方? 4. 什么是静态库,什么是动态库,二者有啥区别? 5. 常 ...

  5. C语言编程中函数指针的定义及使用

    C语言中函数指针的定义: typedef int (*funcPtr)(int, int)表示定义了一个函数指针funcPtr,这个函数指针只能指向如下: int add(int, int).int ...

  6. 【转】 嵌入式C语言编程中Inline函数的应用

    源地址:https://blog.csdn.net/vigour1000/article/details/9622037 有一段儿时间没写写经验笔记了,哎,也是自己这一段时间以来(其实最近一直是这个状 ...

  7. Go语言编程中字符串切割方法小结

    1.func Fields(s string) []string,这个函数的作用是按照1:n个空格来分割字符串最后返回的是[]string的切片 复制代码代码如下: import ( "fm ...

  8. c语言编程中%g是什么格式

    %g用来输出实数,它根据数值的大小,自动选f格式或e格式(选择输出时占宽度较小的一种),且不输出无意义的0.即%g是根据结果自动选择科学记数法还是一般的小数记数法 printf("%g\n& ...

  9. C 语言项目中.h文件和.c文件的关系

    http://blog.csdn.net/xingkong_678/article/details/38639847 关于两者以前的关系,要从N年以前说起了~ long long ago,once a ...

随机推荐

  1. Java连接各种数据库写法

    # 示例配置参考,涵盖几乎所有的主流数据库 ############# Oracle数据库 ######################## #   数据库驱动名 driver=oracle.jdbc ...

  2. Intellij IDEA 2015 导入MyEClipse工程

    一.步骤说明 File->New->Projet from existing sources,选择要导入的项目,并且导入项目; 打开 “open module settings”进行设置: ...

  3. Java关键字-----------------java中synchronized关键字的用法

    在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...

  4. 使用Sublime Text搭建python调试环境[转]

    pycharmt等IDE虽然用着爽,但毕竟在速度.资源上还是比较让人不爽的. 使用IDE无非是图个方便省事,特别是像我这种有些记性差的来说. IDE说起来方便于的几个地方就是: 1.语法颜色高亮 2. ...

  5. mysqldump导出数据时,某些表不导出,排除某些表,不导出某些表

    需求说明: 今天一同事问,在通过mysqldump导出数据库的时候,能不能把某些表不导出,或者叫做排除在外呢, 记得应该是可以实现,就搜索了下,通过mysqldump的--ignore-table参数 ...

  6. MQ选型对比

    现公司选择RocketMQ作为消息队列服务器,用于异步处理,应用解耦,流量削锋和消息通讯四个场景.RocketMQ特性参见:Rocketmq整体分析. PS: http://blog.csdn.net ...

  7. Zoomit的用法总结

    今天才发现Zoomit,相见恨晚.总结一下zoomit的使用方法,备用. Zoomit是一款超赞的演示辅助工具.具有屏幕缩放.屏幕画笔.倒计时功能.且无需安装,点开即用. 1. 屏幕缩放 Ctrl + ...

  8. 字符集和编码——Unicode(UTF&UCS)深度历险

    计算机网络诞生后,大家慢慢地发现一个问题:一个字节放不下一个字符了!因为需要交流,本地化的文字需要能够被支持. 最初的字符集使用7bit来存储字符,因为那时只需要存下一些英文字母和符号.后来虽然扩展到 ...

  9. G - Supermarket

    A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold ...

  10. 关于SMI、MSI、SCI、INTx各种中断小结【转】

    转载自http://blog.csdn.net/huangkangying/article/details/11178425 目录(?)[-] MSI VS INTxPin-based interru ...