Linux系统编程 | 线程原语(1)

Linux系统编程 | 线程原语(1)

pthread_create函数

函数原型:

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

函数作用:

创建一个新线程。 其作用对应于进程中的fork()函数;

返回值:

成功:0;失败:错误号;

函数参数:

thread:传出参数,线程创建成功后所对应的线程ID。在Linux环境下pthread_t本质是unsigned long int类型,其它系统下有可能是结构体;

attr:指定线程属性,通常情况下传NULL,表示使用默认纯种属性。当然可以根据需要修改该参数;

start_routine:函数指针,指向线程主函数(线程体),即线程创建成功后所执行的函数。当该函数运行结束后,则该线程也对应结束;

arg:线程主函数的参数。

函数使用说明:

  1. 当一个线程调用pthread_create函数后,不会暂停或阻塞,直接继续往下运行。而所创建的线程则跳转到参数start_routine所指向的线程主函数运行;
  2. start_routine指向的函数所对应的参数从哪里获得?是由pthread_create参数的arg参数所传递的。arg参数是void *类型,可以根据需要传入任意类型的参数;
  3. 线程主函数的返回值也是void *类型,也可以转化为任意类型的参数。当线程主函数退出时,相应的线程也结束,可以调用pthread_join得到线程主函数的返回值;
  4. 线程创建成功后,新创建的线程的id被写入到pthread_create的thread参数中。线程id的类型是thread_t,它只在当前进程中保证是唯一的。

pthread_self函数

函数原型:

pthread_t pthread_self(void);

函数作用:

获取线程ID,类似于进程中的getpid()函数。

返回值:

成功:返回0;失败:无返回;

注意事项:

线程ID只保证在进程内部是唯一的,但进程间,线程ID有可能会存在相同的情况。

pthread_exit函数

函数原型:

void pthread_exit(void *retval);

函数作用:

将当前进程退出;

函数参数:

retval,表示线程退出状态,通常传NULL,表示不关心线程退出状态;

注意事项:

  1. 线程中,禁止使用exit函数,这样会导致进程内所有线程都退出,并且进程也退出;
  2. 线程退出时,退出状态将保存在retval参数中,如果不关心线程退出状态,则retval传NULL。
 #include <stdio.h>
 #include <pthread.h>
 #include <unistd.h>

 int var = 100;

 void *tfn(void *arg)
 {
     var = 200;

    printf("this is a thread, tid: %lu\n", pthread_self()); // 使用pthread_self获取线程号
    printf("the arg is: %d\n", *(int *)arg);    // arg强转回整形
    printf("var changed in thread: %d\n", var); // 同一进程内全局变量共享
    pthread_exit(NULL);     //线程退出使用pthread_exit
    return NULL;
}

int main()
{
    pthread_t tid;
    int arg = 5;

    printf("this is main, pid: %d\n", getpid());    // 获取进程号使用getpid
    pthread_create(&tid, NULL, tfn, (void *)&arg);  // 使用arg传递参数到线程主函数
    sleep(1);   // 睡眠1秒是为了保证线程能有机会执行
    return 0;
}

---------------

我是良许,世界500强外企 Linux 开发工程师,专业生产 Linux 干货。