5、linux c 线程 - 上

news2025/3/25 2:13:34

【四】线程

1. 线程的创建

#include <pthread.h>
​
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*routine)(void *), void *arg);
  • pthread_t *thread:指向线程标识符的指针,用于存储新创建线程的 ID。

  • const pthread_attr_t *attr:线程属性指针,通常传 NULL 使用默认属性。

  • void *(*routine)(void *):线程执行的函数指针,即线程开始执行的函数。

  • void *arg:传递给线程函数的参数,可以是任意类型,但需要正确转换。

返回值

  • 成功:返回 0。

  • 失败:返回非零错误码。

特点

  • 创建线程需要时间,如果主进程很快退出,线程可能无法执行。

  • 主进程退出时,其创建的所有线程也会随之退出。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    return NULL;
}
​
int main() {
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, thread_function, NULL);
    if (ret != 0) {
        perror("pthread_create failed");
        return 1;
    }
    printf("Main process, PID: %d\n", getpid());
    sleep(3); // 确保线程有时间运行
    return 0;
}

2. 线程的退出

pthread_exit

#include <pthread.h>
​
void pthread_exit(void *retval);
  • void *retval:线程的返回值,可以是任意类型,但需要正确转换。

特点

  • 调用 pthread_exit 可以使线程正常退出。

  • 主进程退出时,其创建的所有线程也会随之退出。

示例代码

#include <stdio.h>
#include <pthread.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    pthread_exit((void *)0); // 线程正常退出
    return NULL;
}
​
int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_function, NULL);
    printf("Main process, waiting for thread...\n");
    sleep(3);
    return 0;
}

3. 获取线程 ID

pthread_self

#include <pthread.h>
​
pthread_t pthread_self(void);

特点

  • 返回当前线程的 ID。

  • 可以通过 pthread_create 的第一个参数获取线程 ID,也可以在线程内部调用 pthread_self 获取。

示例代码

#include <stdio.h>
#include <pthread.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    return NULL;
}
​
int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_function, NULL);
    printf("Main process, PID: %d\n", getpid());
    sleep(1);
    return 0;
}

4. 线程间参数传递

参数传递方式

pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*routine)(void *), void *arg);
  • 通过地址传递参数:注意类型的转换。

  • 值传递:编译器可能会告警,需要程序员自己保证数据长度正确。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    int num = *((int *)arg); // 转换为 int 类型
    printf("Thread is running, received number: %d\n", num);
    free(arg); // 释放分配的内存
    return NULL;
}
​
int main() {
    pthread_t tid;
    int *num = (int *)malloc(sizeof(int));
    *num = 42;
    pthread_create(&tid, NULL, thread_function, (void *)num);
    printf("Main process, sent number: %d\n", *num);
    sleep(1);
    return 0;
}

5. 线程的回收

pthread_join

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);
  • pthread_t thread:要回收的线程 ID。

  • `void retval**:用于存储线程的返回值,可以是NULL`。

返回值

  • 成功:返回 0。

  • 失败:返回非零错误码。

特点

  • pthread_join 是阻塞函数,如果回收的线程未结束,则一直等待。

示例代码

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

// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    return (void *)0;
}

int main() {
    pthread_t tid;
    void *retval;
    pthread_create(&tid, NULL, thread_function, NULL);
    printf("Main process, waiting for thread...\n");
    int ret = pthread_join(tid, &retval);
    if (ret != 0) {
        perror("pthread_join failed");
        return 1;
    }
    printf("Thread exited with status: %ld\n", (long)retval);
    return 0;
}

6. 线程的分离

1、使用 pthread_detach

#include <pthread.h>

int pthread_detach(pthread_t thread);

2、创建线程时设置分离属性

#include <pthread.h>

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

特点

  • 分离线程在退出时会自动回收资源,无需显式调用 pthread_join

示例代码

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

// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_create(&tid, &attr, thread_function, NULL);
    printf("Main process, PID: %d\n", getpid());
    sleep(3);
    return 0;
}
  1. 查看线程

ps -eLf | grep [名字]

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

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

相关文章

2024年河南省职业院校 技能大赛高职组 “大数据分析与应用” 赛项任务书(四)

2024 年河南省职业院校 技能大赛高职组 “大数据分析与应用” 赛项任务书&#xff08;四&#xff09;&#xff09; 背景描述&#xff1a;任务一&#xff1a;Hadoop 完全分布式安装配置&#xff08;25 分&#xff09;任务二&#xff1a;离线数据处理&#xff08;25 分&#xff0…

dify创建第一个Agent

1、首先LLM模型必须支持 Function Calling 由于deepseek-R1本地化部署时还不支持&#xff0c;所以使用 qwq模型。 2、创建空白 Agent 3、为Agent添加工具 4、测试 当未添加时间工具时 询问 时间 如下 5、开启时间工具 询问如下

⭐算法OJ⭐判断二叉搜索树【树的遍历】(C++实现)Validate Binary Search Tree

图论入门【数据结构基础】&#xff1a;什么是树&#xff1f;如何表示树&#xff1f; 之前我们有分别讲解二叉树的三种遍历的相关代码实现&#xff1a; ⭐算法OJ⭐二叉树的前序遍历【树的遍历】&#xff08;C实现&#xff09;Binary Tree Preorder Traversal ⭐算法OJ⭐二叉树的…

2. 商城前端部署

商城客户端前端部署 https://gitee.com/newbee-ltd/newbee-mall-api-go 使用开源新蜂商城的前端&#xff0c;git clone到本地 然后在vscode终端依次输入下列指令&#xff08;配置好vue3相关环境的前提下&#xff09;&#xff1a; npm install npm i --legacy-peer-deps npm …

鸿蒙生态开发

鸿蒙生态开发概述 鸿蒙生态是华为基于开源鸿蒙&#xff08;OpenHarmony&#xff09;构建的分布式操作系统生态&#xff0c;旨在通过开放共享的模式连接智能终端设备、操作系统和应用服务&#xff0c;覆盖消费电子、工业物联网、智能家居等多个领域。以下从定义与架构、核心技术…

基于STM32进行FFT滤波并计算插值DA输出

文章目录 一、前言背景二、项目构思1. 确定FFT点数、采样率、采样点数2. 双缓存设计 三、代码实现1. STM32CubeMX配置和HAL库初始化2. 核心代码 四、效果展示和后话五、项目联想与扩展1. 倍频2. 降频3. 插值3.1 线性插值3.2 样条插值 一、前言背景 STM32 对 AD 采样信号进行快…

【Oracle资源损坏类故障】:详细了解坏块

目录 1、物理坏块与逻辑坏块 1.1、物理坏块 1.2、逻辑坏块 2、两个坏块相关的参数 2.1、db_block_checksum 2.2、db_block_checking 3、检测坏块 3.1、告警日志 3.2、RMAN 3.3、ANALYZE 3.4、数据字典 3.5、DBVERIFY 4、修复坏块 4.1、RMAN修复 4.2、DBMS_REPA…

996引擎-接口测试:背包

996引擎-接口测试:背包 背包测试NPC参考资料背包测试NPC CONSTANT = require("Envir/QuestDiary/constant/CONSTANT.lua"); MsgUtil = require("Envir/QuestDiary/utils/996/MsgUtil.lua");

Electron打包文件生成.exe文件打开即可使用

1 、Electron 打包&#xff0c;包括需要下载的内容和环境配置步骤 注意&#xff1a;Electron 是一个使用 JavaScript、HTML 和 CSS 构建跨平台桌面应用程序的框架 首先需要电脑环境有Node.js 和 npm我之前的文章有关nvm下载node的说明也可以去官网下载 检查是否有node和npm环…

单播、广播、组播和任播

文章目录 一、单播二、广播三、组播四、任播代码示例&#xff1a; 五、各种播的比较 一、单播 单播&#xff08;Unicast&#xff09;是一种网络通信方式&#xff0c;它指的是在网络中从一个源节点到一个单一目标节点对的传输模式。单播传输时&#xff0c;数据包从发送端直接发…

Cursor+Claude-3.5生成Android app

一、Android Studio下载 https://developer.android.com/studio?hlzh-tw#get-android-studio 等待安装完成 二、新建工程 点击new project 选择Empty Activity 起一个工程名 当弹出这个框时 可以在settings里面选择No proxy 新建好后如下 点击右边模拟器&#xff0c…

QT Quick(C++)跨平台应用程序项目实战教程 3 — 项目基本设置(窗体尺寸、中文标题、窗体图标、可执行程序图标)

目录 1. 修改程序界面尺寸和标题 2. 窗体图标 3. 修改可执行程序图标 上一章创建好了一个初始Qt Quick项目。本章介绍基本的项目修改方法。 1. 修改程序界面尺寸和标题 修改Main.qml文件&#xff0c;将程序宽度设置为1200&#xff0c;程序高度设置为800。同时修改程序标题…

Transformers x SwanLab:可视化NLP模型训练(2025最新版)

HuggingFace 的 Transformers 是目前最流行的深度学习训框架之一&#xff08;100k Star&#xff09;&#xff0c;现在主流的大语言模型&#xff08;LLaMa系列、Qwen系列、ChatGLM系列等&#xff09;、自然语言处理模型&#xff08;Bert系列&#xff09;等&#xff0c;都在使用T…

VSCode 抽风之 两个conda环境同时在被激活

出现了神奇的(toolsZCH)(base) 提示符&#xff0c;如下图所示&#xff1a; 原因大概是&#xff1a;conda 环境的双重激活&#xff1a;可能是 conda 环境没有被正确清理或初始化&#xff0c;导致 base 和 toolsZCH 同时被激活。 解决办法就是 &#xff1a;conda deactivate 两次…

Mybatis的基础操作——03

写mybatis代码的方法有两种&#xff1a; 注解xml方式 本篇就介绍XML的方式 使用XML来配置映射语句能够实现复杂的SQL功能&#xff0c;也就是将sql语句写到XML配置文件中。 目录 一、配置XML文件的路径&#xff0c;在resources/mapper 的目录下 二、写持久层代码 1.添加mappe…

React:React主流组件库对比

1、Material-UI | 官网 | GitHub | GitHub Star: 94.8k Material-UI 是一个实现了 Google Material Design 规范的 React 组件库。 Material UI 包含了大量预构建的 Material Design 组件&#xff0c;覆盖导航、滑块、下拉菜单等各种常用组件&#xff0c;并都提供了高度的可定制…

python每日十题(6)

】函数定义&#xff1a;函数是指一组语句的集合通过一个名字&#xff08;函数名&#xff09;封装起来&#xff0c;要想执行这个函数&#xff0c;只需要调用其函数名即可。函数能提高应用的模块性和代码的重复利用率 在Python语言中&#xff0c;用关键字class来定义类 在Python语…

1.Go - Hello World

1.安装Go依赖 https://go.dev/dl/ 根据操作系统选择适合的依赖&#xff0c;比如windows&#xff1a; 2.配置环境变量 右键此电脑 - 属性 - 环境变量 PS&#xff1a; GOROOT&#xff1a;Go依赖路径&#xff1b; GOPATH&#xff1a;Go项目路径&#xff1b; …

优先队列 priority_queue详解

说到&#xff0c;priority_queue优先队列。必须先要了解啥是堆与运算符重载(我在下方有解释)。 否则只知皮毛&#xff0c;极易忘记寸步难行。 但在开头&#xff0c;还是简单的说下怎么用 首先&#xff0c;你需要调用 #include <queue> 在main函数中&#xff0c;声明…

《信息系统安全》(第一次上机实验报告)

实验一 &#xff1a;网络协议分析工具Wireshark 一 实验目的 学习使用网络协议分析工具Wireshark的方法&#xff0c;并用它来分析一些协议。 二实验原理 TCP/IP协议族中网络层、传输层、应用层相关重要协议原理。网络协议分析工具Wireshark的工作原理和基本使用规则。 三 实…