IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 线程学习笔记总结 -> 正文阅读

[C++知识库]线程学习笔记总结

进程概述

进程:有独立的进程地址空间,有独立的PCB
线程:没有独立的地址空间,是共享的,有独立的PCB
Linux下,线程是最小的执行单位,进程是最小的分配资源的单位

LWP: 轻量级进程也就是线程
命令
ps -Lf pid
可以查看该进程的线程号
在这里插入图片描述

线程创建

      int pthread_create(pthread_t *thread,       //传出参数,表示创建的线程的线程id 
                         const pthread_attr_t *attr, //表示线程属性,传NULL表示使用默认属性
                         void *(*start_routine) (void *),//回调函数,会自动调用
                         void *arg);                  //上一个参数的参数

返回值:成功返回0
失败返回perror

#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<unistd.h>
void* tfn(void*arg)
{
    printf("phread:pid = %d,tid = %lu\n",getpid(),pthread_self());
}
int main()
{
    pthread_t tid;
    printf("mian : pid = %d ,tid = %lu\n",getpid(),pthread_self());
    int ret=pthread_create(&tid,NULL,tfn,NULL);
    if(ret!=0)
    {
        perror("pthread");
    }
    sleep(1);
    return 0;
}

线程退出

pthread_exit函数

       void pthread_exit(void *retval);

参数是传出参数,此函数的作用是终止一个调用他的线程
eg:循环创建五个子线程,终止第三个子线程

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
void func()
{
      pthread_exit(NULL);
}
void*tfn(void*argv)
{
    int i=(int)argv;
    sleep(i);
    if(i==2)//第三个线程退出
    {
       // exit(1);//表示退出进程
       //return NULL;//表示返回到函数调用者那里
       func();
      
    }
    printf("I am %d ,pthread: pid = % d,tid = %lu\n",i+1,getpid(),pthread_self());
}
int main()
{
    int i=0;
    int ret;
    pthread_t tid;
    for(i=0;i<5;i++)
    {
        ret=pthread_create(&tid,NULL,tfn,(void*)i);
        if(ret!=0)
        {
            perror("pthread_create");
            exit(1);
        }
    }
    //sleep(i);
    printf("i am main\n");
    //return 0;
    pthread_exit(NULL);
}

执行结果:
在这里插入图片描述

pthread_cancel函数

 int pthread_cancel(pthread_t thread);

回收特定线程,传入参数是要终止的线程id
为了看到效果,用一个死循环代码来展示效果

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
void*tnf(void*arg)
{   while(1)
  {
    printf(" thread: pid = %d,tid = %lu\n",getpid(),pthread_self());
    sleep(1); 
  }
}
int main()
{
    pthread_t tid;
    int ret =pthread_create(&tid,NULL,tnf,NULL);
    if(ret<0)
    {
        perror("create");
        exit(1);
    }
    sleep(3);
    ret=pthread_cancel(tid);
    while(1);
    return 0;
}

效果:
在这里插入图片描述

pthread_join函数(回收线程)

阻塞等待线程退出,并且获得线程退出状态(返回值),很类似于进程中的waitpid函数

int pthread_join(pthread_t thread, void **retval);

参数:
thread 要堵塞等待退出的线程id
retval 退出状态
eg:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
typedef struct pdf
{
    int var;
    char arr[100];
}pdf;
void*tnf(void*arg)
{
    struct pdf* p1;
    p1=(pdf*)malloc(sizeof(pdf));
    p1->var=100;
    strcpy(p1->arr,"hello world");
    return (void*)p1;
}
int main()
{
    pthread_t tid;
    pdf* p1;
    int ret =pthread_create(&tid,NULL,tnf,NULL);
    pthread_join(tid,(void**)&p1);
    printf("tar=%d,arr=%s\n",p1->var,p1->arr);
    return 0;
}

结果:
在这里插入图片描述

线程分离pthread_detach

线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不由其它线程获取,而直接自己自动释放

 int pthread_detach(pthread_t thread);

参数:所要分离的线程

#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
void*tfn(void*arg)
{
    printf("thread : pid = %d, tid = %lu\n",getpid(),pthread_self());
    return NULL;
}
int main()
{
    pthread_t tid;
    int ret=pthread_create(&tid,NULL,tfn,NULL);
    if(ret!=0)
    {
        perror("create error");
        exit(1);
    }
    sleep(2);
    ret=pthread_detach(tid);
    if(ret!=0)
    {
        fprintf(stderr,"pthread_deach error:%s\n",strerror(ret));
        exit(1);
    }
    ret=pthread_join(tid,NULL);
    if(ret!=0)
    {
        fprintf(stderr,"pthread_join error:%s\n",strerror(ret));
        exit(1);
    }
    return 0;
}

结果:
在这里插入图片描述
当我们对线程分离后,再当我们使用线程退出函数就会报无效参数的错误

线程属性

属性值不能直接设置,须使用相关函数进行操作,初始化的函数为pthread_attr_init,这个函数必须在pthread_create函数之前调用。之后须用pthread_attr_destroy函数来释放资源。线程属性主要包括如下属性:作用域(scope)、栈尺寸(stack size)、栈地址(stack address)、优先级(priority)、分离的状态(detached state)、调度策略和参数(scheduling policy and parameters)。默认的属性为非绑定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。

所用函数

 int pthread_attr_init(pthread_attr_t *attr);//初始化
 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);//设置分离非分离属性
 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachst
  ..........还有很多函数
 int pthread_attr_destroy(pthread_attr_t *attr);//销毁

使用

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
void*tfn(void*argv)
{
    printf("thread : pid=%d,tid=%lu\n",getpid(),pthread_self());
    return NULL;
}
int main()
{
    pthread_attr_t attr;
    pthread_t tid;
    int ret=pthread_attr_init(&attr);   //初始化
    if(ret!=0)
    {
        fprintf(stderr,"attr_init error:%s\n",strerror(ret));
        exit(1);
    }
    ret=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//设置线程属性为分离属性
    if(ret!=0)
    {
        fprintf(stderr,"attr_setdeatachstate error:%s\n",strerror(ret));
        exit(1);
    }
    ret=pthread_create(&tid,&attr,tfn,NULL);
    if(ret!=0)
    {
        fprintf(stderr,"attr_create error:%s\n",strerror(ret));
        exit(1);
    }
    ret=pthread_attr_destroy(&attr);//销毁
    if(ret!=0)
    {
        fprintf(stderr,"attr_destroy error:%s\n",strerror(ret));
        exit(1);
    }
    sleep(1);
    ret=pthread_join(tid,NULL);//测试是否成功分离线程
    if(ret!=0)
    {
        fprintf(stderr,"create error:%s\n",strerror(ret));
        exit(1);
    }
       return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 11:40:56  更:2022-05-10 11:42:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 20:56:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码