C/C++ 线程超详细讲解(系统性学习day10)

news2024/11/17 12:45:38

目录

前言

一、线程基础

1.概念

 2.一个进程中多个线程特征

2.1 线程共有资源

2.2 线程私有资源  

3.线程相关的api函数

 3.1 创建线程

创建线程实例代码如下:

 需要特别注意的是:

-lpthread和-pthread的区别

3.2 给线程函数传参  

传参实例代码如下:

3.3 给线程收尸

收尸实例代码如下: 

 二、线程状态转换函数说明

1.初始化条件休眠

2.条件休眠,挂起线程 

3.唤醒线程 

4.设置取消状态 

 5.设置取消方式

6.取消线程 

三 、线程状态转换图片(如图清晰可见)

总结


前言

线程指的是在一个进程中独立执行的最小单位。简单来说,线程是进程中的一个执行流,可以理解为执行程序的一条执行路径。本篇文章将对线程进行超详细讲解。


一、线程基础

1.概念

(1)线程:在进程空间中执行,也是一个动态的过程。

(2)一个进程对应一个程序,一个线程对应程序中的一个函数

(3)线程是该函数的一次在执行过程,该函数称为线程函数。

 2.一个进程中多个线程特征

2.1 线程共有资源

(1)可执行的指令(.text)
(2)静态数据(.data/.bss/.heap)
(3)进程中打开的文件描述符
(4)信号处理函数
(5)当前工作目录
(6)用户ID
(7)用户组ID

2.2 线程私有资源  

(1)线程ID (TID)
(2)PC(程序计数器)和相关寄存器
(3)堆栈
(4)局部变量
(5)返回地址
(6)错误号 (errno)
(7)信号掩码和优先级
(8)执行状态和属性

3.线程相关的api函数

 3.1 创建线程

头文件:

#include <pthread.h>
Compile and link with -pthread.

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);
//参数1 ----- 保存线程id的变量的地址
//参数2 ----- 线程属性,一般为NULL,表示使用默认属性
//参数3 ----- 线程函数指针,必须是下面的格式:
             void * xxx_fun (void * arg)
             {
                     线程执行代码
             }
//参数4  ----- 传给线程函数的参数
//返回值 ---- 成功:0 ,失败:错误码

创建线程实例代码如下:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void* fun(void* arg)
{
    int i;

    for(i = 0; i  < 7; i++){
        printf("我是fun\n");
        sleep(1);
    }

    return 0;
}

int main(void)
{
    int i;
    pthread_t tid;

    //fun();
    if(pthread_create(&tid,NULL,fun,NULL)){
        perror("pthread_create");
        exit(1);
    }
    for(i = 0; i  < 7; i++){
        printf("我是主函数\n");
        sleep(1);
    }
    return 0;
}
 需要特别注意的是:

编译时,需要链接线程库
gcc pthread_create.c -o pthread_create  -lpthread

-lpthread和-pthread的区别

两个选项都是用于链接 pthread 库的选项,但它们有一些细微的差别。

-lpthread 是告诉链接器去链接 pthread 库,这是一个标准的链接选项,可以用于链接任何库。

-pthread 是告诉编译器在编译时需要使用 pthread 库,这是一个非标准的编译选项,只能在支持它的编译器上使用。

在大多数情况下,使用 -lpthread 是更好的选择,因为它是标准的链接选项,可以在不同的编译器和操作系统上使用。而 -pthread 只能在支持它的编译器上使用

3.2 给线程函数传参  

传参实例代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

typedef struct{
    int sno;
    char name[20];
    float score;
}St;

void* fun(void* arg)
{
    St *p = (St*)arg;
    //printf("%d\n",*(int*)arg);
    //printf("%s\n",(char*)arg);
    printf("%d %s %.2f\n",p->sno,p->name,p->score);
    return 0;
}

int main(void)
{
    pthread_t tid;
    //int a = 120;
    //char str[] = "hello world";
    St s = {1001,"peter",98.56};

    if(pthread_create(&tid,NULL,fun,&s)){
	perror("pthread_create");
	exit(1);
    }
    
    sleep(1);
    return 0;
}

3.3 给线程收尸

 int pthread_join(pthread_t thread, void **retval);
//参数1 ---- 线程的id
//参数2 ---- 保存线程返回值的指针变量的地址
//返回值 ---- 成功:0,失败:错误码

收尸实例代码如下: 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

typedef struct{
    int sno;
    char name[20];
    float score;
}St;

void* fun(void* arg)
{
    static int a = 112200;
    St *p = (St*)arg;
    //printf("%d\n",*(int*)arg);
    //printf("%s\n",(char*)arg);
    printf("%d %s %.2f\n",p->sno,p->name,p->score);
    return &a;
}

int main(void)
{
    pthread_t tid;
    int *p;
    //int a = 120;
    //char str[] = "hello world";
    St s = {1001,"peter",98.56};

    //创建子线程
    if(pthread_create(&tid,NULL,fun,&s)){
	perror("pthread_create");
	exit(1);
    }
    
    //给指定线程收尸,如果子线程没有结束,则主线程阻塞
    //if(pthread_join(tid,NULL)){
    if(pthread_join(tid,(void**)&p)){
	perror("pthread_join");
	exit(1);
    }
    printf("*p = %d\n",*p);

    return 0;
}

 二、线程状态转换函数说明

1.初始化条件休眠

头文件:#include <pthread.h>

int pthread_cond_init (pthread_cond_t * __cond,const pthread_condattr_t * __cond_attr)
 * 功能:初始化条件休眠
 * 参数:
    pthread_cond_t * __cond - 指向被初始化的条件变量
    const pthread_condattr_t * __cond_attr- 指向条件变量的属性,使用默认值NULL
 * 返回值:
    失败:负数,绝对值是错误码

2.条件休眠,挂起线程 

头文件:#include <pthread.h>

int pthread_cond_wait (pthread_cond_t * __cond, pthread_mutex_t *__mutex);
 * 功能:条件休眠,挂起线程(调用该函数的线程被阻塞了,函数不返回,且休眠状态)
 * 参数:
    pthread_cond_t * __cond - 指向条件变量
    pthread_mutex_t *__mutex- 指向互斥锁
 * 返回值:
    失败:负数,绝对值是错误码

3.唤醒线程 

头文件:#include <pthread.h>

int pthread_cond_signal (pthread_cond_t *__cond);
 * 功能:唤醒线程(调用该函数的唤醒被pthread_cond_wait阻塞的线程)
 * 参数:
    pthread_cond_t * __cond - 指向条件变量
 * 返回值:
    失败:负数,绝对值是错误码

4.设置取消状态 

头文件:#include <pthread.h>

int pthread_setcancelstate (int __state, int *__oldstate);
 * 功能:设置取消状态
 * 参数:
    int __state    - 使能还不使能
            使能取消线程,PTHREAD_CANCEL_ENABLE
    int *__oldstate- 保存老状态
 * 返回值:
    失败 - 负数绝对值是错误码

 5.设置取消方式

头文件:#include <pthread.h>

int pthread_setcanceltype (int __type, int *__oldtype);
 * 功能:设置取消方式
 * 参数:
    int __type    - 取消方式
            PTHREAD_CANCEL_ASYNCHRONOUS - 异步取消
            PTHREAD_CANCEL_DEFERRED - 取消延迟
    int *__oldtype- 保存老方式
 * 返回值:
    失败 - 负数绝对值是错误码

6.取消线程 

头文件:#include <pthread.h>

 int pthread_cancel (pthread_t __th);

/*
 * 功能:取消线程
 * 参数:
    pthread_t __th - 线程ID
 * 返回值:
    失败 - 负数绝对值是错误码

三 、线程状态转换图片(如图清晰可见)


总结

        本篇文章针对C/C++ 线程进行详细讲解,希望能够帮到大家!

        以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!

       希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1082566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

生命在于学习——Stable Diffution(Mac端)

一、前言 最近一段时间研究了一下Stable Diffution&#xff0c;Windows和MAC端都搭建成功了&#xff0c;也尝试了各种功能&#xff0c;后续会学习新的使用姿势&#xff0c;写一篇文章记录一下。 二、介绍 1、Stable Diffution是什么 Stable Diffusion&#xff0c;是一种AI绘…

如何处理前端安全性问题(XSS、CSRF等)?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

记一次生产大对象及GC时长优化经验

最近在做一次系统整体优化,发现系统存在GC时长过长及JVM内存溢出的问题,记录一下优化的过程 面试的时候我们都被问过如何处理生产问题&#xff0c;尤其是线上oom或者GC调优的问题更是必问&#xff0c;所以到底应该如何发现解决这些问题呢&#xff0c;用真实的场景实操&#xff…

PHP LFI 利用临时文件Getshell

PHP LFI 利用临时文件 Getshell 姿势-安全客 - 安全资讯平台 LFI 绕过 Session 包含限制 Getshell-安全客 - 安全资讯平台 目录 PHP LFI 利用临时文件Getshell 临时文件 linux 和 windows的 临时文件存储规则 linux和windows对临时文件的命名规则 PHPINFO()特性 原理 条…

前端项目--尚医通学习分享

这段时间跟着线上课程完成了一个项目&#xff1a;商医通&#xff08;基于Vue3TypeScript的医院挂号平台&#xff09;。具体我就不过多地介绍其具体功能以及详细的实现步骤了&#xff0c;感兴趣的小伙伴直接&#xff1a;传送门 。该文章我就分享一下在该项目中学习到的一些知识点…

如何退出commit_message页面

虽然提示命令了&#xff0c;但我试了&#xff0c;退不出去。我没搞明白。。。 退出编辑 Crtl Z设置git的编辑器为vim或vi git config --global core.editor vim如果没有vim编辑器&#xff0c;设置成vi编辑器也行 git config --global core.editor vi重新提交 再次进入commi…

【高等数学】极限(上)(最全万字详解)

文章目录 1、数列的极限1.1、数列极限的定义1.2、为什么收敛数列极限是唯一的&#xff1f;1.3、为什么收敛数列是有界的&#xff1f;1.4、数列极限的保号性1.4.1、极限保数列值1.4.2、数列值保极限值 1.5、收敛数列与其子列之间的关系 2、函数极限概念2.1、函数极限的定义2.1.1…

[Unity][VR]Passthrough2-创建一个基本的Passthrough应用

上一期我们对PassthroughXR项目做好了基本的项目设置,今天我们就开始构建一个基本的Passthrough应用。 我们还是从基本场景开始。先把默认的main camera删除。因为后续我们会引入OVR Rig对象,这个对象自带Camera用来实现VR视角。 在Project面板我们搜索OVR camera rig。看见…

【java学习】方法的重载overload(19)

文章目录 1. 重载的概念 1. 重载的概念 在同一个类中&#xff0c;允许存在一个以上的同名方法&#xff0c;只要它们的参数个数或者参数类型不同即可。 重载的特点&#xff1a;     与返回值类型无关&#xff0c;只看参数列表&#xff0c;且参数列表必须不同。 ( 参数个数或…

nodejs+vue家教管理系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1nodejs简介 4 2.2 express框架介绍 6 2.3 B/S结构 4 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性…

k8s强制删除pod、svc、namespace(Terminating)

如果名称空间、pod、pv、pvc全部处于“Terminating”状态时&#xff0c;此时的该名称空间下的所有控制器都已经被删除了&#xff0c;之所以出现pod、pvc、pv、ns无法删除&#xff0c;那是因为kubelet 阻塞&#xff0c;有其他的资源在使用该namespace&#xff0c;比如CRD等&…

【ElasticSearch】更新es索引生命周期策略,策略何时对索引生效

大家好&#xff0c;我是好学的小师弟&#xff0c;今天和大家讨论下更新es索引生命周期策略后&#xff0c;策略何时对索引生效 结论: 若当前索引已应用策略A(旧)&#xff0c;更新完策略A后&#xff0c;新的策略A会立即对原来的已经应用该策略的索引生效&#xff1b;若当前索引…

Webpack 解决:ReferenceError: dist is not defined 的问题

1、问题描述&#xff1a; 其一、报错为&#xff1a; ReferenceError: dist is not defined 中文为&#xff1a; ReferenceError&#xff1a;dist 未定义 其二、问题描述为&#xff1a; 想在 webpack 的配置中&#xff0c;创建一个 dist 文件夹来存放 npm run build 打包后…

docker- harbor私有仓库部署与管理

什么是 harbor harbor是一个开源的云原生镜像仓库&#xff0c;它允许用户存储、签名、和分发docker镜像。可以将 harbor 看作是私有的docker hub &#xff0c;它提供了更新安全性和控制性&#xff0c;让组织能够安全的存储和管理镜像 harbor RBAC&#xff08;基于角色访问控制…

zsh: command not found: conda问题解决

参考:https://zhuanlan.zhihu.com/p/158703094 一、问题介绍与环境介绍 系统为macOS Catalina 10.15.4 所用终端为zsh 安装了oh-my-zsh之后conda命令在终端中不可用。 二、原因分析 终端中zsh的可访问的程序一般放在/bin, /usr/bin, /usr/local/bin&#xff0c;/bin目录下&…

Linux sed命令

在Linux系统中&#xff0c;有许多强大的文本处理工具&#xff0c;其中之一就是sed&#xff08;Stream Editor&#xff09;命令。sed是一个用于对文本进行编辑、替换、删除和过滤操作的命令行工具&#xff0c;一次处理一行内容。它具有强大的正则表达式支持和灵活的文本处理功能…

华为李鹏:加速5G商业正循环,拥抱更繁荣的5.5G(5G-A)

2023年10月10日&#xff0c;在华为主办的第十四届全球移动宽带论坛上&#xff0c;华为高级副总裁、运营商BG总裁李鹏面向来自全球的运营商和产业伙伴&#xff0c;提出抓住网络需求和趋势的力量——“面向后天的业务&#xff0c;积极规划明天的网络&#xff0c;加速5G商业正循环…

堆叠、集群技术

1.堆叠、集群技术的概述 堆叠、集群简介 堆叠&#xff08;iStack&#xff09;&#xff0c;将多台支持堆叠特性的交换机通过堆叠线缆连接在一起&#xff0c;从逻辑上虚拟成一台交换设备&#xff0c;作为一个整体参与数据转发。 集群&#xff08;Cluster Switch System&#xf…

Fisher辨别分析

问题要求 在UCI数据集上的Iris和Sonar数据上验证算法的有效性。训练和测试样本有三种方式&#xff08;三选一&#xff09;进行划分&#xff1a; &#xff08;一&#xff09; 将数据随机分训练和测试&#xff0c;多次平均求结果 &#xff08;二&#xff09;K折交叉验证 &…

Vuex存值取值与异步请求处理

目录 前言 一、Vuex简介 1.Vuex是什么 2.Vuex的核心概念 3.使用Vuex的好处 4.Vuex执行流程 二、Vuex的使用步骤 1.安装Vuex 2.创建store模块&#xff0c;分别维护state/actions/mutations/getters 3.使用Vuex存储值&#xff0c;获取值和改变值 1.state.js---存值 2.…