就像每个进程都有一个进程ID一样,每个线程也有一个线程ID。
进程ID是用数据类型pid_t表示的,而线程ID是用pthread_t进行表示的。
由于线程ID实现的时候是用线程结构来实现的,所以不能作为整数处理,下面的函数用来对两个线程进行比较:
#include <pthread.h>
int pthread_equal(pthread_t tid1,pthread_t tid2);
//返回值,若相等返回非0,否则,返回0
线程可以通过调用pthread_self函数获得自身的线程ID
#include <pthread.h>
pthread_t pthread_self(void);
//返回值:调用线程的线程ID
新增的线程可以通过调用pthread_create函数创建
#include <pthread.h>
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
//若成功返回0,否则,返回错误编号
1) pthread_t *thread:传递一个 pthread_t 类型的指针变量,也可以直接传递某个 pthread_t 类型变量的地址。pthread_t 是一种用于表示线程的数据类型,每一个 pthread_t 类型的变量都可以表示一个线程。
2) const pthread_attr_t *attr:用于手动设置新建线程的属性,例如线程的调用策略、线程所能使用的栈内存的大小等。大部分场景中,我们都不需要手动修改线程的属性,将 attr 参数赋值为 NULL,pthread_create() 函数会采用系统默认的属性值创建线程。
3) void *(*start_routine) (void *):以函数指针的方式指明新建线程需要执行的函数,该函数的参数最多有 1 个(可以省略不写),形参和返回值的类型都必须为 void* 类型。void* 类型又称空指针类型,表明指针所指数据的类型是未知的。使用此类型指针时,我们通常需要先对其进行强制类型转换,然后才能正常访问指针指向的数据。
4) void *arg:指定传递给 start_routine 函数的实参,当不需要传递任何数据时,将 arg 赋值为 NULL 即可。
创建进程实例
#include "apue.h"
#include <pthread.h>
pthread_t ntid;
void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid=getpid();
tid=pthread_self();
printf("%s pid %u tid %u (0x%x)\n",s,(unsigned int)pid,
(unsigned int)tid,(unsigned int)tid);
}
void * thr_fn(void * arg)
{
printids("new thread:");
return ((void *)0);
}
int main()
{
int err;
err=pthread_create(&ntid,NULL,thr_fn,NULL);
if(err!=0)
err_exit(err,"can not create thread");
printids("main thread: ");
sleep(1);
exit(0);
}
运行结果