Linux/C++多线程编程学习笔记——多线程基本操作

目录

1.线程创建

2.线程退出

3.线程回收

4.线程分离


1.线程创建

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

参数:

pthread_t *thread:传出参数,这个子线程的id的地址

const pthread_attr_t *attr:线程属性一般写为NULL

void *(*start_routine) (void *):此线程需要执行的函数指针,函数返回值需要为void*类型

void *arg:此线程需要执行的函数参数的地址,如果多个参数,则定义一个结构体封装参数

返回值:

创建成功返回0,否则返回错误号

头文件:

#include

注意,当主线程销毁时,子线程也就不存在了,因为一个进程的所有线程共享同一块内存空间

2.线程退出

如果想要主线程销毁时,不影响子线程继续执行,需要用到线程退出函数

void pthread_exit(void* retval)

参数:

void* retval:自带数据,一般为当前线程想要返回的数据,不返回设置为NULL

用法:

可以在主线程逻辑的末尾使用,主线程退出后,该虚拟地址空间不会被释放,当子线程执行完毕后,该地址空间会被操作系统回收

头文件:

#include

3.线程回收

用于主线程回收子线程内核资源,当主线程执行到这个函数时,会阻塞并等待指定的子线程执行完毕退出后,再去继续执行回收资源,这样就避免了主线程在子线程还没有执行完毕就退出的问题,该函数每次只能回收一个线程

int pthread_join(pthread_t tid, void** retval)

参数:

pthread_t tid:当前需要退出线程的id

void** retval:子线程需要返回给主线程的内容,如果不返回设置NULL,配合pthread_exit来使用

返回值:

回收成功返回0,否则返回错误号

对于retval的一些说法:

子线程返回数据有两种方式:

(1)子线程退出时,把返回数写在pthread_exit的retval参数中,然后主线程从pthread_join的retval中读取,需要定义一个全局变量

struct Test
{
    int a;
    int b;
};
Test test;
void* work(void* arg)
{
    //cout << "child thread " << pthread_self() << endl;
    test.a = 1;
    test.b = 2;
    pthread_exit(&test);
    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;
    int thread1 = pthread_create(&tid, NULL, work, NULL);
    //cout << "main thread " << pthread_self() << endl;
    void* p;
    pthread_join(tid, &p);
    Test* pt = (Test*)p;
    cout << "a: " << pt->a << " b: " << pt->b << endl;

    return 0;
}

结果:

a: 1 b: 2

(2)在主线程的栈空间中定义传出变量,然后通过pthread_create的最后一个参数传入到子线程中,无需定义全局变量,也无需使用pthread_exit函数

struct Test
{
    int a;
    int b;
};

void* work(void* arg)
{
    //cout << "child thread " << pthread_self() << endl;
    Test* test = (Test*)arg;
    test->a = 1;
    test->b = 2;
    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;
    Test test;
    int thread1 = pthread_create(&tid, NULL, work, &test);
    //cout << "main thread " << pthread_self() << endl;
    pthread_join(tid, NULL);
    cout << "a: " << test.a << " b: " << test.b << endl;

    return 0;
}

结果:

a: 1 b: 2

4.线程分离

如果主线程负责回收子线程资源,当主线程执行到pthread_join函数时,会被一直阻塞,导致不能继续处理主线程后续的逻辑

当主线程调用线程分离函数pthread_detach时,子线程就和主线程分离了,主线程不再回收子线程的资源,子线程退出后资源将被其他进程回收

虽然分离了,但是当主线程销毁后,子线程依然也不复存在,所以为了不影响子线程执行,会在pthread_detach使用pthread_exit函数

int pthread_detach(pthread_t tid)

参数:

pthread_t tid:需要被分离线程的id

返回值:

为0分离成功

void* work(void* arg)
{
    //cout << "child thread " << pthread_self() << endl;
    for (int i = 0; i < 5; ++i)
    {
        cout << i << endl;
    }
    
    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;
    int thread1 = pthread_create(&tid, NULL, work, NULL);
    //cout << "main thread " << pthread_self() << endl;
    pthread_detach(tid);
    pthread_exit(NULL);

    return 0;
}

返回:

0
1
2
3
4

学习网站推荐:

爱编程的大丙 线程 | 爱编程的大丙

你可能感兴趣的:(c++,开发语言,linux)