Linux 多线程(C语言) 备查

news2025/1/27 13:04:56

基础

1)线程在运行态就绪态不停的切换。
2)每个线程都有自己的栈区寄存器

1)进程资源分配的最小单位,线程是操作系统调度执行的最小单位
2)线程的上下文切换的速度比进程快得多
3)从应用程序A中启用应用程序B才考虑使用多进程

线程API

线程创建
//每个线程都有唯一的线程ID,类型为pthread_t,是一个无符号长整形数
pthread_t pthread_self(void);	// 返回当前线程的线程ID
#include <pthread.h> //线程库的名字叫pthread, 全名: libpthread.so libptread.a
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
参数:
	thread:	传出参数,是无符号长整形数,线程创建成功, 会将线程ID写入到这个指针指向的内存中
	attr:	线程的属性, 一般情况下使用默认属性即可,NULL
	start_routine: 函数指针,创建出的子线程的处理动作,也就是该函数在子线程中执行。
	arg: 	作为实参传递到 start_routine 指针指向的函数内部
	返回值:	线程创建成功返回0,创建失败返回对应的错误号
-------------------创建线程 案列-----------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

// 子线程的处理代码
void* working(void* arg)
{
    printf("我是子线程, 线程ID: %ld\n", pthread_self());
    for(int i=0; i<9; ++i)
    {
        printf("child == i: = %d\n", i);
    }
    return NULL;
}

int main()
{
    // 1. 创建一个子线程
    pthread_t tid;
    pthread_create(&tid, NULL, working, NULL);
    printf("我是主线程, 线程ID: %ld\n", pthread_self());    //子线程不会执行下边的代码, 主线程执行
    for(int i=0; i<3; ++i)
    {
        printf("i = %d\n", i);
    }
    sleep(1); //主线程等待子线程执行完毕
    //如果主线程退出了, 虚拟地址空间就被释放了, 子线程就一并被销毁了。
    return 0;
}

执行

线程退出

1)想要让线程退出,但是不会导致虚拟地址空间的释放(针对于主线程),可以调用线程库中的线程退出函数
2)只要调用该函数,当前线程就马上退出,并且不会影响到其他线程的正常运行,不管是在子线程或者主线程中都可以使用。

void pthread_exit(void *retval);
参数: 
	线程退出的时候携带的数据,当前子线程的主线程会得到该数据。如果不需要使用,指定为NULL
线程回收

1)这是一个阻塞函数, 子线程在运行这个函数就阻塞
2)子线程退出, 函数解除阻塞, 回收对应的子线程资源, 类似于回收进程使用的函数 wait()

int pthread_join(pthread_t thread, void **retval);
参数:
	thread: 要被回收的子线程的线程ID
	retval: 二级指针, 指向一级指针的地址, 是一个传出参数, 这个地址中存储了pthread_exit() 传递出的数据,如果不需要这个参数,可以指定为NULL
	返回值:线程回收成功返回0,回收失败返回错误号。

很多情况下还需要在主线程中回收子线程资源,所以主线程一般都是最后退出

子线程数据 回收

子线程退出的时候可以使用 pthread_exit() 的参数将数据传出,在回收这个子线程的时候可以通过 phread_join(pthread_t thread, void **retval) 的第二个参数来接收子线程传递出的数据

pthread_exit(void *retval);
-------------------子线程数据回收 案列-----------------------
// 定义结构
struct Persion{
    int id;
    char name[36];
    int age;
};

// 子线程的处理代码
void* working(void* arg){
    struct Persion* p = (struct Persion*)arg;
   // 使用主线程的栈内存
   p->age  =12;
   strcpy(p->name, "tom");
   p->id = 100;
   // 该函数的参数将这个地址传递给了主线程的pthread_join()
   pthread_exit(p);
    return NULL;
}

int main(){
    // 1. 创建一个子线程
    pthread_t tid;

    struct Persion p;
    // 主线程的栈内存传递给子线程
    pthread_create(&tid, NULL, working, &p);
    
    // 2. 子线程不会执行下边的代码, 主线程执行
    void* ptr = NULL;
    // ptr是一个传出参数, 在函数内部让这个指针指向一块有效内存
    // 这个内存地址就是pthread_exit() 参数指向的内存
    pthread_join(tid, &ptr);// 会阻塞等待子线程退出,并回收资源
    
    // 打印信息
    printf("name: %s, age: %d, id: %d\n", p.name, p.age, p.id);
    printf("子线程资源被成功回收...\n");   
    return 0;
}

在这里插入图片描述

线程分离

子线程和主线程分离,当子线程退出的时候,其占用的内核资源就被系统的其他进程接管并回收了。

// 参数就子线程的线程ID, 主线程就可以和这个子线程分离了
int pthread_detach(pthread_t thread);
线程取消

在一个线程中杀死另一个线程。使用这个函数杀死一个线程需要分两步:
1)在线程A中调用线程取消函数pthread_cancel,指定杀死线程B,这时候线程B是死不了的
2)在线程B中进程一次系统调用(从用户区切换到内核区),否则线程B可以一直运行。

// 参数是子线程的线程ID
int pthread_cancel(pthread_t thread);
参数:
	要杀死的线程的线程ID
	返回值:函数调用成功返回0,调用失败返回非0错误号。

在这里插入图片描述

线程比较

在Linux中线程ID本质就是一个无符号长整形,可以直接使用比较操作符比较两个线程的ID,但是线程库是可以跨平台使用的。

int pthread_equal(pthread_t t1, pthread_t t2);
参数:
	t1 和 t2 是要比较的线程的线程ID
	返回值:如果两个线程ID相等返回非0值,如果不相等返回0

详细教程可转

爱编程的大丙

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

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

相关文章

flink源码分析之功能组件(四)-slot管理组件I

简介 本系列是flink源码分析的第二个系列&#xff0c;上一个《flink源码分析之集群与资源》分析集群与资源&#xff0c;本系列分析功能组件&#xff0c;kubeclient&#xff0c;rpc&#xff0c;心跳&#xff0c;高可用&#xff0c;slotpool&#xff0c;rest&#xff0c;metrics&…

智能优化算法应用:基于黄金正弦算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于黄金正弦算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于黄金正弦算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.黄金正弦算法4.实验参数设定5.算法结果6.参考…

【每日一题】拼车+【差分数组】

文章目录 Tag题目来源解题思路方法一&#xff1a;差分 写在最后 Tag 【差分数组】【数组】【2023-12-02】 题目来源 1094. 拼车 解题思路 本题朴素的解题思路是统计题目中提到的每一个站点的车上人数&#xff0c;如果某个站点的车上人数大于车上的座位数直接返回 false&…

Linux部署HDFS集群

&#xff08;一&#xff09;VMware虚拟机中部署 ps、其中node1、node2、node3替换为自己相应节点的IP地址&#xff0c;或者host文件中配置过的主机名&#xff0c;或者看前置准备 或者查看前置准备&#xff1a;Linux部署HDFS集群前置准备 1.下载压缩包 https://www.apache.or…

Leetcode—1094.拼车【中等】

2023每日刷题&#xff08;四十七&#xff09; Leetcode—1094.拼车 模拟实现代码 bool carPooling(int** trips, int tripsSize, int* tripsColSize, int capacity) {int arr[1003] {0};int numPassenger 0, fromidx 0, toidx 0;for(int i 0; i < tripsSize; i) {num…

力扣66. 加一

文章目录 力扣66. 加一示例代码实现总结收获 力扣66. 加一 示例 代码实现 class Solution {public int[] plusOne(int[] digits) {int ndigits.length;for(int in-1;i>0;i--){if(digits[i]!9){digits[i];for(int ji1;j<n;j){digits[j]0;}return digits;}}int[] resnew i…

爬虫学习(一)

文章目录 文件目录结构打开文件操作 爬取网页的理解尝试 文件目录结构 打开文件操作 爬取网页的理解尝试 这个放回值为请求正常

人工智能中的模型评估

1 概述 1.1 定义 人工智能&#xff08;AI&#xff09;模型评估是一个关键的过程&#xff0c;用于确定模型在特定任务上的性能和有效性。这个过程涉及使用各种技术和指标来衡量模型的准确度、可靠性、泛化能力以及其他重要特性。在不同的应用场景中&#xff0c;模型评估的具体…

OpenSSH 漏洞修复升级最新版本

Centos7系统ssh默认版本一般是OpenSSH7.4左右&#xff0c;低版本是有漏洞的而且是高危漏洞&#xff0c;在软件交付和安全扫描上是过不了关的&#xff0c;一般情况需要升级OpenSSH的最新版本 今天详细说下升级最新版本的处理过程&#xff08;认真看会发现操作很简单&#xff0c…

设计模式-结构型模式之外观设计模式

文章目录 七、外观模式 七、外观模式 外观模式&#xff08;Facade Pattern&#xff09;隐藏系统的复杂性&#xff0c;并向客户端提供了一个客户端可以访问系统的接口。它向现有的系统添加一个接口&#xff0c;来隐藏系统的复杂性。 这种模式涉及到一个单一的类&#xff0c;该类…

【vue-router】useRoute 和 useRouter 的区别

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

pandas美化表格并导出到Excel

美化Excel表格用两种方式,一种是用Pandas自带的Dataframe.style类并通过CSS来改变样式,另外一种是通过Excel引擎来直接修改Excel样式。 Dataframe.style Dataframe.style可以美化Pandas样式。导出样式到Excel的功能只有openpyxl渲染引擎支持。 大于平均数的单元格背景变色…

【重点】【双指针】11. 盛最多水的容器

题目 注意&#xff1a;二维接雨水&#xff0c;有墙的&#xff0c;有线的&#xff0c;着这个属于线的。 class Solution {public int maxArea(int[] height) {if (height.length < 2) {return 0;}int left 0, right height.length - 1, res 0;while (left < right) {…

【Java 基础】16 泛型

文章目录 什么是泛型&#xff1f;泛型的声明泛型的使用泛型方法通配符和泛型上下界1&#xff09;通配符2&#xff09;泛型上下界 泛型的好处注意事项 泛型提供了一种在编写代码时更好地 支持类型安全的机制。通过泛型&#xff0c;我们可以编写更加 通用、 灵活、 可读性高的…

C#,数值计算——插值和外推,三次样条插值(Spline_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 三次样条插值 /// Cubic Spline Interpolation /// Cubic spline interpolation object. Construct with x and y vectors, and /// (optionally) values of the first…

Vue基础知识点梳理

在Vue中&#xff0c;被用来响应地更新HTML属性的指令是v-model页面挂载成功之后会触发哪一个钩子函数mounted挂载之后会进行页面的渲染v-on是动作元素不属于条件渲染指令 在Vue中&#xff0c;下列关于Vue实例对象说法不正确的是&#xff08;&#xff09;。A.Vue实例对象是通过n…

Vulhub-信息泄露

1.Jetty WEB-INF 敏感信息泄露漏洞&#xff08;CVE-2021-28164&#xff09; docker-compose up -d 启动环境&#xff0c;显示8080端口被占用 修改 docker-compose.yml 中的映射端口 curl 访问 http://192.168.48.129:8090/WEB-INF/web.xml 显示404&#xff1a; 通过 %2e 绕过…

C++的类和对象(一)

目录 1、面向过程和面向对象初认识 2、为什么要有类 3、类的定义 类的两种定义方式 4、类的访问限定符 5、类的作用域 5.1 为什么要有作用域&#xff1f; 5.2类作用域 6、类的实例化 6.1类的实例化的定义 6.2类的实例化的实现 6.3经典面试题 7、类对象 7.1类对…

HarmonyOS——解决本地模拟器无法选择设备的问题

在使用deveco studio进行鸿蒙开发的时候&#xff0c;可能会遇到本地模拟器已经启动了&#xff0c;但是仍然无法选择本地模拟器中的设备&#xff0c;尤其在MAC环境中尤为常见。 解决办法&#xff1a; 先打开IDE启动本地模拟器&#xff0c;等模拟器启动后&#xff0c;退出IDE重新…

【每日OJ —— 572. 另一棵树的子树】

每日OJ —— 572. 另一棵树的子树 1.题目&#xff1a;572. 另一棵树的子树2.解法2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目&#xff1a;572. 另一棵树的子树 2.解法 2.1.算法讲解 通过深度优先遍历&#xff0c;来判断二叉树root的每个节点的值是否和subRoot的每个节点…