线程和进程一样,也有唯一的线程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,如果不休眠可能就会退出,那么有可能新线程还没运行,整个进程就退出了,还是和操作系统实现有关
