C++多线程开发(一)多线程

参考:大丙老师线程

1.个数控制

 

 2.创建线程

3.编译的时候需要注意:

 

4.线程退出

子线程是在主线程中创建的,因此主线程退出之后子线程也就结束运行,但是子线程的结束不影响主线程的的运行。

 

 如下的示例,子线程并不会在终端打印出id信息,因为主线程运行结束之后就退出了并且释放了地址空间,因此子线程也无法运行了。

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
void* callback(void* arg);
int main(){
    pthread_t tid;
    pthread_create(&tid,NULL,callback,NULL);
    printf("main thread d:%ld\n",pthread_self());
}

void* callback(void* arg){
    printf("sun thread d:%ld\n",pthread_self());
    return NULL;
}

 

 因此主线程的退出需要调用退出函数保证子线程还能正常运行,修改一下主线程(main函数)。

int main(){
    pthread_t tid;
    pthread_create(&tid,NULL,callback,NULL);
    printf("main thread d:%ld\n",pthread_self());
    pthread_exit(NULL);
}

 

5.线程回收:主线程回收子线程的内核资源

 

 代码如下:

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

struct ThInfo{
    int num;
    int age;
};

void* callback(void* arg);
int main(){
    pthread_t tid;
    pthread_create(&tid,NULL,callback,NULL);
    printf("main thread d:%ld\n",pthread_self());
    void* arg;
    pthread_join(tid,&arg);
    struct ThInfo* info=(struct ThInfo*)arg;
    printf("sub thread age:%d,num:%d\n",info->age,info->num);
}

void* callback(void* arg){
    struct ThInfo info;
    info.age=9;
    info.num=100;
    printf("sun thread d:%ld\n",pthread_self());
    pthread_exit(&info);
    return NULL;
}

 

运行结果如下:

 

子线程的回收参数不正确,是因为主线程退出时将栈的地址空间释放掉了,而子线程的临时变量也是放置在同一块空间中的,因此被释放掉之后就被其他值覆盖了。

解决方案:

(1)将callback中的结构体变量ThInfo indo设置为全局变量,这样就被放置在全局区,主线程中即可在全局区访问到正确的数值;

(2)callback中的结构体变量ThInfo indo在main函数中声明,相当于在栈中分配了一块空间用于接受保存子线程退出时的参数,将其地址传递给callback,callback将需要返回的结果写在这个空间中;

注意:指针与地址会有相应变化;

int main(){
    pthread_t tid;
    struct ThInfo *info;
    pthread_create(&tid,NULL,callback,info);
    printf("main thread d:%ld\n",pthread_self());
    void* arg;
    pthread_join(tid,&arg);
    info=(struct ThInfo*)arg;
    printf("sub thread age:%d,num:%d\n",info->age,info->num);
}

void* callback(void* arg){
    struct ThInfo* info=(struct ThInfo*)arg;
    info->age=9;
    info->num=100;
    printf("sun thread d:%ld\n",pthread_self());
    pthread_exit(info);
    return NULL;
}

 6.线程分离

 

子线程退出的时候,内核资源由其他进程接管回收,因此不需要主线程回收,也就不需要调用pthread_join()了,进而不会阻塞主进程。

int main(){
    pthread_t tid;
    pthread_create(&tid,NULL,callback,NULL);
    pthread_detach(tid);
    pthread_exit(NULL);
}

 

7.线程取消

 

第一步好理解,就是在A线程中调用pthread_cancel;

 

第二步的意思是,A中调用取消函数时并不会立刻结束B线程,而是要等到B中有系统调用的过程才会结束,比如调用printf系统调用,那么B就会结束。

 

posted on 2021-09-19 13:49  freden  阅读(634)  评论(0编辑  收藏  举报