pthread线程系列函数

之前学过的系统函数都是成功返回0,失败返回-1,而错误号保存在全局变量errno中,而pthread库的函数都是通过返回值返回错误号。虽然每个线程也都有一个errno。

由于pthread线程系列函数的错误码不保存在errno中,因此不能直接用perror(3)打印错误信息,可以先用strerror(3)把错误号转换成错误信息再打印。

pthread线程系列函数

创建一个新的线程

原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

参数
thread:返回线程ID
attr:设置线程的属性,attr为NULL表示使用默认属性
start_routine:是个函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数
返回值:成功返回0;失败返回错误码

线程终止

原型 void pthread_exit(void *value_ptr);
参数
value_ptr:value_ptr不要指向一个局部变量,因为当其它线程得到这个返回指针时线程函数已经退出了。
返回值:无返回值

任意一个线程调用了exit或_exit,整个进程的所有线程都终止。

等待线程结束

原型 int pthread_join(pthread_t thread, void **value_ptr);
参数
thread:线程ID
value_ptr:它指向一个指针,后者指向线程的返回值
返回值:成功返回0;失败返回错误码

返回线程ID

原型 pthread_t pthread_self(void);
返回值:成功返回线程id

取消一个执行中的线程

原型 int pthread_cancel(pthread_t thread);
参数
thread:线程ID
返回值:成功返回0;失败返回错误码

将一个线程分离

原型 int pthread_detach(pthread_t thread);
参数
thread:线程ID
返回值:成功返回0;失败返回错误码

线程被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态。不能对一个已经处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL

最后对比下进程与线程的相关函数

进程                线程
pid_t               pthread_t
frok                pthread_create
waitpid             pthread_join
exit                pthread_exit
在main函数中return   在线程入口函数中return
僵尸进程             僵尸线程
waitpid             pthread_join pthread_detach
kill                pthread_cancel

自杀方式结束线程:pthread_exit,在线程入口函数中return
它杀方式线程结束: pthread_cancel

pthread线程系列函数小程序

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<string.h>

#define ERR_EXIT(m) \
    do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)

void *routine(void *arg)
{
    int i;
    for (i = 0; i < 20; i++)
    {
        printf("B");
        fflush(stdout);
        usleep(20);
        /*
            if (i == 3)
                pthread_exit("ABC");
            */
    }
    return "DEF";
}

int main(void)
{
    pthread_t tid;
    int ret;
    if ((ret = pthread_create(&tid, NULL, routine, NULL)) != 0)
    {
        fprintf(stderr, "pthread create: %s\n", strerror(ret));
        exit(EXIT_FAILURE);
    }

    int i;
    for (i = 0; i < 20; i++)
    {
        printf("A");
        fflush(stdout);
        usleep(20);
    }

    void *value;
    if ((ret = pthread_join(tid, &value)) != 0)
    {
        fprintf(stderr, "pthread create: %s\n", strerror(ret));
        exit(EXIT_FAILURE);
    }

    printf("\n");

    printf("return msg=%s\n", (char *)value);
    return 0;
}

创建一个线程,主线程打印A,新线程打印B,主线程调用pthread_join等待新线程退出,打印退出值。在新线程中也可调用pthread_exit退出。