APUE:第十一章——线程

谁说胖子不能爱 提交于 2020-01-13 13:21:41

11.2 概念

在这里插入图片描述
在这里插入图片描述

11.3 线程标识

进程ID使用pid_t标识,线程ID使用pthread_t表示。
进程ID在整个系统中是唯一的,线程ID只在其所属的进程中有效。

线程ID用pthread_t数据类型表示,实现的时候可以使用结构体实现,也可以使用无符号长整型表示。

通过函数pthread_equal函数可以比较两个线程ID是否相同。

#include <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2);
//相同则返回非0值,不同则返回0

线程可以调用pthread_t pthread_self(void);获得自身的线程ID。

#include <pthread.h>
pthread_t pthread_self(void);

11.4 线程创建

#include <pthread.h>
int pthread_create(pthread_t* restrict tidp, const pthread_attr_t* restrict attr, void* (*start_rtn)(void), void* restrict arg);
//成功返回0,失败返回错误编号

tidp指向创建出的线程的ID;
attr用于设置线程的属性;
start_rtn为线程执行的地址,为函数指针,函数接收一个void*类型的参数arg,如果有多个参数,需要将参数放入结构体中,让arg指向这个结构体。

在这里插入图片描述
测试程序,打印主线程与子线程的ID:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

pthread_t ntid;

void printtids(const char* s)
{
    pid_t pid;
    pthread_t tid;

    pid = getpid();
    tid = pthread_self();

    printf("%s: pid: %u, tid: %u (0x%x)\n", s, pid, (unsigned int)tid, (unsigned int)tid);
}

void* thr_fn(void* arg)
{
    printtids("new thread: ");//子线程中调用printtids
    return (void*)0;
}

int main()
{
    int err;
    err = pthread_create(&ntid, NULL, thr_fn, NULL);
    if(err != 0){
        printf("thread create error\n");
        exit(0);
    }

    printtids("main thread: ");//主线程中调用printtids
    sleep(1);
    return 0;
}

运行结果:
在这里插入图片描述
注意在编译时加上-lpthread选项,由于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时,在编译中要加-lpthread参数。

11.5 线程终止

进程中的任一线程调用exit、_exit等都会使整个进程退出,进程中的线程也就终止。

单个线程的退出方式有三种:
1)执行线程函数然后返回;
2)线程被同一进程中的其他线程取消;
3)线程调用pthread_exit()函数;

#include <pthread.h>
void pthread_exit(void* rval_ptr);

进程中的其他线程可以使用pthread_join函数访问rval_ptr这个指针;

#include <pthread.h>
int pthread_join(pthread_t thread, void** rval_ptr);

调用pthread_join的线程会一直阻塞直到thread退出。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void* thr_fun1(void* arg)
{
    printf("thread 1 returning\n");
    return (void*)1;
}

void* thr_fun2(void* arg)
{
    printf("thread 2 exiting\n");
    pthread_exit((void*)2);
}

int main()
{
    pthread_t tid1, tid2;
    int err;
    void *rval_ptr;

    if(pthread_create(&tid1, NULL, thr_fun1, NULL)){
        printf("thread 1 create failed\n");
        exit(0);
    }

    if(pthread_create(&tid2, NULL, thr_fun2, NULL)){
        printf("thread 2 create failed\n");
        exit(0);
    }

    if(pthread_join(tid1, &rval_ptr)){
        printf("thread join failed\n");
        exit(0);
    }
    printf("thread 1 exit code : %d\n", (int)(rval_ptr));
    
    if(pthread_join(tid2, &rval_ptr)){
        printf("thread join failed\n");
        exit(0);
    }
    printf("thread 2 exit code : %d\n", (int)(rval_ptr));

    return 0;
}

在这里插入图片描述

线程同步

关于线程同步参考其他文章,共包含:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!