简单创建线程

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

发表评论