Linux 多线程基础

文章目录

  • 前言
  • 一、多线程基础函数
      • 1. pthread_create
      • 2. pthread_self
      • 3. pthread_exit
      • 4. pthread_join
      • 5. pthread_cancel
      • 6. pthread_detach
  • 二、线程间的共享数据
  • 三、多线程 ,进程对比
  • 总结

前言


一、多线程基础函数

1. pthread_create

创建新的线程。

	#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

参数说明:

  • thread: 用于存储新线程的ID。
  • attr: 线程属性,通常使用NULL表示默认属性。
  • start_routine: 线程的入口函数,线程将从该函数开始执行。
  • arg: 传递给线程入口函数的参数。

pthread_t 的具体实现可能因不同的操作系统而有所变化,但在 Linux 中,它通常是一个整数类型(例如 unsigned long int 或 unsigned int

2. pthread_self

函数返回当前线程的线程标识符(pthread_t 类型)。

	pthread_t pthread_self(void);

线程标识符 tid ,用于在其他线程或线程管理函数中标识当前线程。


3. pthread_exit

用于终止当前单一线程的执行并返回一个指定的退出状态。

	void pthread_exit(void *retval);

函数参数:

  • retval:指向线程的退出状态的指针。可以是指向任何类型的指针,表示线程退出时传递的信息。

通过 pthread_exit,线程可以返回一个指定的退出状态,以便创建者线程或进程可以通过 pthread_join 等函数获取该状态

注意
在多线程环境中,不使用 exit 函数,取而代之使用 pthread_exit 函数,将单个线程退出。
因为 在 任何线程里 exit 会导致进程退出,这样会使其他线程为工作就结束。主线程退出不能使用 return 或 exit。


4. pthread_join

用于阻塞等待指定的线程终止,并获取该线程的退出状态。
它允许一个线程等待另一个线程的完成,以便协调线程的执行顺序和获取线程的返回结果。

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

函数参数:

  • thread:要等待的线程的线程标识符(pthread_t 类型)。
  • retval:一个指针的指针,用于存储被等待线程的退出状态。

函数说明:
(1). pthread_join 函数阻塞当前线程,直到指定的线程终止
(2). 当所等待的线程终止后,调用 pthread_join 的线程将被唤醒并继续执行。
(3). pthread_join 函数返回后,调用线程可以通过 retval 参数获取被等待线程的退出状态
(4). 被等待的线程在终止时必须使用 pthread_exit 函数返回一个退出状态,以便被等待线程能够获取到退出状态。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>void* my_pthread (void *arg)
{int *val = (int*)arg;printf("*val = %d\n",*val);sleep(2);printf("pid = %d, tid = %ld\n", getpid(),pthread_self());	// 获取线程idpthread_exit((void*)val);   // 结束线程,并返回退出状态
}int main(void)
{pthread_t tid;int ret;int val = 10;int *threaf_status;printf("main : pid = %d\n", getpid());ret = pthread_create(&tid,NULL, my_pthread, (void*)&val);	// 创建线程if(ret != 0){printf("pthread_create err\n");}pthread_join(tid, (void **)&threaf_status);	// 阻塞等待回收线程的状态printf("status : %d\n", *threaf_status);pthread_exit(NULL);
}

5. pthread_cancel

用于向指定线程发送取消请求,请求线程终止执行。

	int pthread_cancel(pthread_t thread);

取消点 (Cancellation Point):

取消点是一个线程能够响应取消请求的特定函数调用点。
标准的 POSIX 函数(例如 sleep、read、write 等)都是取消点,线程在这些函数调用时能够接收取消请求。
线程也可以使用 pthread_testcancel 函数主动检查取消请求,并在适当的地方终止自己的执行。

6. pthread_detach

用于将一个已经创建但还未被其他线程回收的线程标记为可分离状态,以便操作系统在线程终止时自动回收线程资源。

	int pthread_detach(pthread_t thread);

在线程创建之后,但在其他线程调用 pthread_join 之前,可以调用 pthread_detach 来将线程设为分离状态。

可分离状态的线程可以在终止时自动释放系统资源,无需其他线程显式回收资源。这样可以避免对线程进行 pthread_join 调用等待线程结束。

二、线程间的共享数据

线程默认共享数据段,代码段等地址空间,常用的是全局变量。
线程共享 全局变量,静态变量, 文件描述符,动态分配的堆内存,数据结构

对于共享资源的访问需要考虑线程安全性,使用适当的同步机制(如互斥锁、条件变量、读写锁等)来避免数据竞争和不一致性的问题。

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>int num = 20;void* my_pthread (void *arg)
{num = 322;
printf("2 : num = %d\n", num);pthread_exit(NULL);   // 结束线程
}int main(void)
{pthread_t tid;int ret;printf("1 : num = %d\n", num);ret = pthread_create(&tid,NULL, my_pthread, NULL);	// 创建线程if(ret != 0){printf("pthread_create err\n");}sleep(1);printf("3 : num = %d\n", num);pthread_exit(NULL);
}

在这里插入图片描述

三、多线程 ,进程对比

多线程进程
pthread_create()fork()
pthread_self()getpid()
pthread_exit()exit()
pthread_join()wait() / waitpid()
pthread_cancel()kill()

多线程和进程是并发编程中的两个重要概念,它们有着不同的特点和应用场景。下面是它们之间的比较:

  1. 进程(Process):是操作系统中的一个执行单位,具有独立的内存空间、代码和数据,可以拥有多个线程。
    线程(Thread):是进程中的一个执行流程,共享进程的内存空间和资源,每个线程有自己的栈空间,但代码和数据是共享的。
    资源占用:

  2. 进程:每个进程都有独立的地址空间和系统资源,包括内存、文件描述符、CPU等。创建和销毁进程的开销较大。
    线程:线程共享进程的地址空间和系统资源,包括内存、文件描述符等。创建和销毁线程的开销相对较小。
    切换开销:

  3. 进程:进程切换的开销较大,需要保存和恢复整个进程的上下文。
    线程:线程切换的开销较小,因为线程共享进程的地址空间和资源,只需要保存和恢复线程的上下文。
    通信方式:

  4. 进程:不同进程之间的通信需要使用进程间通信(IPC)机制,如管道、消息队列、共享内存等。
    线程:线程之间可以通过共享内存、全局变量等直接进行通信,不需要额外的通信机制。
    可靠性:

  5. 进程:由于进程拥有独立的地址空间,一个进程的崩溃不会影响其他进程。
    线程:由于线程共享进程的地址空间,一个线程的崩溃可能会导致整个进程的崩溃。


总结

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组名和函数名是指针?指针和引用底层一样?

在2023/8/26日晚上&#xff0c;我看到一个所谓“典”的视频&#xff0c;一开始还没太在意&#xff0c;后面想了想发现我貌似也一直犯了以下的错误&#xff0c;而错误的原因在于我在新手阶段学习C/C并不是查阅文档扎好脚步学习的&#xff0c;而是被铺天盖地的新手学习基础教程里…

基于Java+SpringBoot+Vue前后端分离纺织品企业财务管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

uni-app 分不清的全局变量this, uni, $u, vm, uni.$u, this.$u

项目引入了uview,并将uview所有模块指给uniapp全局变量uni uni.$u$u 在登录页面&#xff0c;或者APP.vue打印以下变量&#xff1a; this, uni, $u, vm, uni.$u, this.$u

2023科隆游戏展:虚幻5游戏百花齐放,云渲染助力虚幻5高速渲染

8月23日&#xff0c;欧洲权威级游戏展示会——科隆游戏展拉开帷幕。今年的参展游戏也相当给力&#xff0c;数十款游戏新预告片在展会上公布&#xff0c;其中有不少游戏使用虚幻5引擎制作&#xff0c;开创了游戏开发新纪元。 虚幻5游戏百花齐放&#xff0c;渲染堪比电影级效果 …

2023年国赛 高教社杯数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林&#xff1f;2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…

2023年国赛 高教社杯数学建模思路 - 案例:粒子群算法

文章目录 1 什么是粒子群算法&#xff1f;2 举个例子3 还是一个例子算法流程算法实现建模资料 # 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法&#xff1f; 粒子群算法&#xff08;Pa…

陕西广电 HG6341C FiberHome烽火 光猫获取超级密码 改桥接模式 提升网速

光猫默认的路由模式实测在100M宽带下只能跑到60M左右&#xff0c;只有改成桥接模式才能跑满&#xff0c;不损失性能。但是改桥接需要给运营商打电话&#xff0c;有的时候不想麻烦他们&#xff0c;这时获取超级密码进行更改就是一个不错的选择了 分析 之前写了一篇HGU B2 光猫的…

基于海洋捕食者算法优化的BP神经网络(预测应用) - 附代码

基于海洋捕食者算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于海洋捕食者算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.海洋捕食者优化BP神经网络2.1 BP神经网络参数设置2.2 海洋捕食者算法应用 4.测试结果&…

PCI9054入门1:硬件引脚定义、时序、FPGA端驱动源码

文章目录 1&#xff1a;PCI9054的FPGA侧&#xff08;local侧引脚定义&#xff09;2&#xff1a;PCI9054的C模式下的读写时序3&#xff1a;FPGA代码部分具体代码&#xff1a; 1&#xff1a;PCI9054的FPGA侧&#xff08;local侧引脚定义&#xff09; 而PCI9054的本地总线端的主要…

【python】jupyter notebook导出pdf和pdf不显示中文问题

文章目录 写在前面1. 使用jupyter notebook导出pdf1.1 安装Pandoc1.2 安装MiKTex1.3 示例导出pdf 2. 中文显示问题2.1 显示中文问题示例2.2 解决办法1&#xff1a;修改tex2.3 解决办法2&#xff1a;修改内置文件 写在前面 使用jupyter notebook导出pdf时&#xff0c;出现了一些…

KVM创建虚拟机可访问外网+可使用Xshell等工具连接

创建虚拟机时使用桥接网络模块即可&#xff0c;如下&#xff1a; 1、创建一个存储卷(虚拟机的磁盘) 2、创建虚拟机时选择网络 3、系统安装完成后配置固定IP地址 vi /etc/sysconfig/network-scripts/ifcfg-eth0ONBOOTyes BOOTPROTOstatic IPADDR16.32.15.60 GATEWAY16.32.15.2…

统计学补充概念-13-逻辑回归

概念 逻辑回归&#xff08;Logistic Regression&#xff09;实际上是一种用于解决分类问题的统计学习方法&#xff0c;尽管其名称中带有"回归"一词&#xff0c;但它主要用于处理分类任务。逻辑回归用于预测一个事件发生的概率&#xff0c;并将其映射到一个特定的输出…

QtWidgets和QtQuick融合(QML与C++融合)

先放一个界面效果吧&#xff01; 说明&#xff1a;该演示程序为一个App管理程序&#xff0c;可以将多个App进行吸入管理。 &#xff08;动画中的RedRect为一个带有QSplashScreen的独立应用程序&#xff09; 左侧边栏用的是QQuickView进行.qml文件的加载&#xff08;即QtQuick…

寻找注册配置中心最佳评测官,赢取丰厚奖品 | 测评开启,开发者请速速集结

评测前请点击文末链接&#xff0c;领取 MSE-Nacos 免费试用&#xff0c;再启动评测。 注册配置中心 MSE-Nacos (以下简称 MSE-Nacos)&#xff0c;即 Nacos 的企业版&#xff0c;开箱即用的 Nacos 云服务&#xff0c;对 Nacos 内核进行企业级稳定性加固&#xff0c;故障自动检测…

01-Flask-简介及环境准备

Flask-简介及环境准备 前言简介特点Flask 与 Django 的比较环境准备 前言 本篇来介绍下Python的web框架–Flask。 简介 Flask 是一个轻量级的 Web 框架&#xff0c;使用 Python 语言编写&#xff0c;较其他同类型框架更为灵活、轻便且容易上手&#xff0c;小型团队在短时间内…

C++string类

目录 一、为什么学习string 二、标准库中的string类 2.1 string类的简介 2.2 成员类型 2.3 成员函数 2.3.1 构造、析构与运算符重载 2.3.2 迭代器 2.3.3 容量 2.3.4 元素的存取 2.3.5 修改 2.3.6 字符串操作 2.4 成员常量 2.5 非成员函数重载 三、string编程题练…

【韩顺平 零基础30天学会Java】数组、排序和查找(2days)

数组、排序、查找和多维数组 数组可以存放多个同一类型的数据。数组也是一种数据类 型&#xff0c;是引用数据类型。 定义一个数组 double[] hens {3,5,1,3.4,2,50} 遍历数组得到数组所有元素的和 hens[下标]&#xff0c;下标是从0开始编号的。 可以通过数组名.lenght得到数组…

azure data studio SQL扩展插件开发笔记

node.js环境下拉取脚手架 npm install -g yo generator-azuredatastudio yo azuredatastudio 改代码 运行 调试扩展&#xff0c;在visual studio code中安装插件即可 然后visual studio code打开进行修改运行即可 image.png 运行后自动打开auzre data studio了&#xff0c; 下面…

如何使用CSS实现一个平滑滚动到页面顶部的效果(回到顶部按钮)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 平滑滚动到页面顶部的效果&#xff08;回到顶部按钮&#xff09;⭐ 创建HTML结构⭐ 编写CSS样式⭐ 编写JavaScript函数⭐ 添加滚动事件监听器⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右…