线程和进程一样,也有唯一的线程ID,它的类型是pthread_t
在Linux里定义如下:
/* Thread identifiers. The structure of the attribute type is not exposed on purpose. */ typedef unsigned long int pthread_t;
而Windows下是一个结构体定义,Cygwin下定义也不同,因此如果要考虑可移植性就不能直接进行比较运算
跟获取自身pid一样,获取自身线程ID可以通过
#include <pthread.h> pthread_t pthread_self(void);
线程ID做比较还提供了一个函数
#include <pthread.h> int pthread_equal(pthread_t tid1, pthread_t tid2);
假如他们线程ID不相等那么返回0,相等非0
创建线程可以通过下面函数:
#include <pthread.h> extern int pthread_create (pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn) (void *), void *restrict arg);
看到这定义的参数我也是醉了,还好意思不难
函数如果成功返回,由tidp指向的内存单元就被设置为新创建的线程的线程ID,实际上就是子线程ID,下面例子有测试
attr参数用于定制各种不同的线程属性,这里设置为NULL,默认属性
新创建的线程会从start_rtn函数的地址开始运行,这个函数只有一个无类型指针参数arg,如果需要向start_rtn函数传递不止一个参数,那么就要把这些参数放到一个结构体中,然后把这个结构的地址作为arg参数传入,这点比较重要
pthread_create创建线程如果失败就会返回错误码,成功就会返回0
下面的小例子,比较一下主线程和子线程的pid,tid,以及比较函数,以及创建线程的第一个参数是否的确是子线程的tid
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> void *thread_function(){ pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("Child thread: pid %u, tid %u\n", (unsigned int)pid, (unsigned int)tid); } int main(){ pid_t mpid; pthread_t mtid, ctid; int err; int tid_bool; err = pthread_create(&ctid, NULL, thread_function, NULL); if (err != 0){ printf("Cannot create thread!\n"); exit(1); } mpid = getpid(); mtid = pthread_self(); tid_bool = pthread_equal(mtid, ctid); if (tid_bool) printf("Main thread and child thread thread_id are the same!\n"); else printf("Main thread and child thread thread_id are the different!\n"); printf("Main thread: pid %u, tid %u\n", (unsigned int)mpid, (unsigned int)mtid); printf("Child thread id: tid %u\n", (unsigned int)ctid); sleep(1); return 0; }
编译的时候记得带上链接库-lpthread,然后运行可以得到下面结果
[lihui@localhost ~]# ./a.out Main thread and child thread thread_id are the different! Main thread: pid 6315, tid 4170016512 Child thread id: tid 4170008320 Child thread: pid 6315, tid 4170008320
可见主线程和子线程所在的进程id一致,子线程id的确和创建线程第一个参数指向的值是一致的
这里主线程需要sleep,如果不休眠可能就会退出,那么有可能新线程还没运行,整个进程就退出了,还是和操作系统实现有关