前言

        以下:

概述

        1.基础

        2.代码演示

        3.练习

        4.分析题

1.基础

一、线程基础概念

  1. 并发执行原理

    • 通过时间片轮转实现多任务"并行"效果

    • 实际为CPU快速切换执行不同线程

  2. 线程 vs 进程

    • 线程共享进程地址空间,切换开销更小

    • 进程拥有独立资源,隔离性更强


二、线程操作函数

1. 线程创建

int pthread_create(
    pthread_t *id,       // 线程ID存储地址
    const pthread_attr_t *attr,  // 属性(NULL为默认)
    void *(*callback)(void*),  // 线程函数
    void *arg           // 传递给线程的参数
);

  • 返回值:成功返回0,失败返回错误码

  • 示例

    pthread_t tid;
    int ret = pthread_create(&tid, NULL, thread_func, NULL);

2. 线程终止

void pthread_exit(void *retval);  // 线程主动退出

  • 注意

    • exit()不同,仅终止当前线程

    • retval可被其他线程通过pthread_join()获取

3. 线程回收

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

  • 功能:阻塞调用线程,直到目标线程结束

  • 参数

    • id:要等待的线程ID

    • retval:接收线程返回值(二级指针)


三、线程控制

1. 线程属性管理
函数功能
pthread_self()获取当前线程ID
pthread_detach(id)设置线程为分离态(不可join)
pthread_cancel(id)向线程发送取消请求
2. 取消状态控制

// 设置取消状态

// 设置取消类型 
pthread_setcanceltype(
    PTHREAD_CANCEL_DEFERRED,  // 延迟取消(默认)
    PTHREAD_CANCEL_ASYNCHRONOUS, // 立即取消
    NULL
);

  • 延迟取消:只在取消点(如sleep()printf())响应取消请求

  • 立即取消:随时可能被终止(危险)


四、关键示例

1. 基础线程示例

void* print_msg(void *arg) {
    printf("Thread ID: %lu\n", pthread_self());
    pthread_exit(NULL);
}

int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, print_msg, NULL);
    pthread_join(tid, NULL);
    return 0;
}

2. 取消请求处理

void* worker(void *arg) {
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

    while(1) {
        printf("Working...\n");
        sleep(1);  // 取消点
    }
    return NULL;
}


五、注意事项

  1. 分离态线程

    • 设置pthread_detach()后:

      • 不能调用pthread_join()

      • 线程结束后自动释放资源

  2. 线程安全

    • 共享数据需通过互斥锁(pthread_mutex_t)保护

    • 避免使用全局变量

  3. 错误处理

    • 所有pthread函数返回0表示成功,非0为错误码

    • 建议用strerror(errno)输出错误信息

2.代码演示

2.1 pthread_create

#include <IO_head.h>
//分支线程
void* callback(void* arg){while(1){printf("division\n");sleep(1);}return NULL;
}int main(int argc,const char* argv[]){pthread_t thread_id;if(pthread_create(&thread_id, NULL, callback, NULL)!=0){printf("error\n");}else{printf("create succeeded\n");}//主线程while(1){printf("main\n");sleep(1);}return 0;
}
ubuntu@ubuntu:~/IO/class3$ cd ~/IO/class4
ubuntu@ubuntu:~/IO/class4$ ./05_thread 
create succeeded
main
division
main
division
main
division

2.2

#include <IO_head.h>
//分支线程
void* callback(void* arg){static int a =200;//important*(int**)arg = &a;return NULL;
}int main(int argc,const char* argv[]){pthread_t thread_id;int* p = NULL;if(pthread_create(&thread_id, NULL, callback, &p)!=0){printf("error\n");}else{printf("create succeeded\n");}//主线程sleep(1);printf("%d\n",*p);return 0;
}
ubuntu@ubuntu:~/IO/class4$ ./06_pointer 
create succeeded
200

2.3

#include <IO_head.h>
//分支线程
void* callback(void* arg){//分支线程idprintf("division thread id = %ld\n", pthread_self());static int num =200;//importantpthread_exit(&num);return NULL;
}int main(int argc,const char* argv[]){pthread_t thread_id;if(pthread_create(&thread_id, NULL, callback, NULL)!=0){printf("error\n");}else{printf("create succeeded\n");}//主线程//主线程idprintf("main thread id = %ld\n", pthread_self());int* p = NULL;pthread_join(thread_id,(void**)&p);printf("main thread:num = %d\n",*p);return 0;
}
ubuntu@ubuntu:~/IO/class4$ ./07_self_exit_join 
create succeeded
main thread id = 139733924939584
division thread id = 139733924935424
main thread:num = 200

3.练习

分段拷贝

#include <IO_head.h>typedef struct message{int ori_des;int new_des;int len;
}message;void RD_WR(int start, int end, int ori_des, int new_des){lseek(ori_des, start, SEEK_SET);lseek(new_des, start, SEEK_SET);char buf;for(int i = start; i<end;++i){read(ori_des, &buf, 1);write(new_des, &buf, 1);}printf("copy succeeded\n");
}void* callback(void* arg){message* mes_p = (message*)arg;RD_WR(mes_p->len/2, mes_p->len, mes_p->ori_des, mes_p->new_des);pthread_exit(NULL);return NULL;
}int main(int argc, const char* argv[]){//文件IO:文件描述符int file_ori_des = open("./01_vfork.c",O_RDONLY);int file_new_des = open("./01_new_vfork.c",O_WRONLY|O_CREAT|O_TRUNC,0777);int len = lseek(file_ori_des,0,SEEK_END);message message_next = {.ori_des = file_ori_des,.new_des = file_new_des,.len = len};pthread_t thread_id;if(pthread_create(&thread_id,NULL,callback,&message_next)!=0){printf("error\n");}else{NULL;}pthread_join(thread_id,NULL);RD_WR(0, len/2, file_ori_des, file_new_des);return 0;
}

4.分析题

4.1解读代码:

结果:

...process1

...process

4.2

for(int i=0;i<3;i++)
{fork()printf("-")
}

运行14次

结语

        以上

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

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

相关文章

MySQL JSON数据类型完全指南:从版本演进到企业实践的深度对话

&#x1f4ca; MySQL JSON数据类型完全指南&#xff1a;从版本演进到企业实践的深度对话 在当今数据驱动的时代&#xff0c;MySQL作为最受欢迎的关系型数据库之一&#xff0c;不断演进以满足现代应用的需求。JSON数据类型的引入&#xff0c;让MySQL在保持关系型数据库优势的同时…

BI × 餐饮行业 | 以数据应用重塑全链路业务增长路径

在竞争激烈的餐饮行业中&#xff0c;数据已成为企业保持竞争力的关键资产。通过深入分析顾客数据&#xff0c;餐饮企业能够洞察消费者的需求和偏好&#xff0c;从而提供更加精准和个性化的服务。此外&#xff0c;利用数据优化业务管理&#xff0c;降低成本&#xff0c;并提高运…

【学习线路】机器学习线路概述与内容关键点说明

文章目录 零、机器学习的企业价值一、基础概念1. 机器学习定义2. 学习类型3. 学习范式 二、核心算法与技术1. 监督学习2. 无监督学习3. 模型评估与优化 三、深度学习与神经网络1. 神经网络基础2. 深度学习框架3. 应用场景 四、工具与实践1. 数据处理2. 模型部署3. 机器学习的生…

Linux 命令:cp

Linux cp 命令详细教程 cp 是 Linux 系统中最常用的命令之一&#xff0c;用于复制文件或目录。它可以将源文件/目录复制到指定的目标位置&#xff0c;支持批量复制、强制覆盖、保留文件属性等功能。下面详细介绍其用法。资料已经分类整理好&#xff1a;https://pan.quark.cn/s…

java分页插件| MyBatis-Plus分页 vs PageHelper分页:全面对比与最佳实践

MyBatis-Plus分页 vs PageHelper分页&#xff1a;全面对比与最佳实践 一、分页技术概述 在Java持久层框架中&#xff0c;分页是高频使用的功能。主流方案有&#xff1a; MyBatis-Plus分页&#xff1a;MyBatis增强工具的内置分页方案PageHelper分页&#xff1a;独立的MyBatis…

PROFINET转MODBUS TCP网关在机械臂通信操作中的应用研究

在特定的汽车零部件生产工厂焊接生产线上&#xff0c;机械臂被应用于焊接作业&#xff0c;其控制体系基于Profinet协议。同时&#xff0c;工厂的自动化控制体系以西门子S7-1200PLC为核心&#xff0c;通过ModbusTCP协议实现数据交换。为实现焊接过程的自动化控制以及生产数据的实…

Mac中如何Chrome禁用更新[update chflags macos]

写在前面 在 macOS 系统中&#xff0c;系统更新提示的小红点常常让人不胜其扰。 尤其是当你希望保持现有系统的稳定性&#xff0c;或因兼容性问题暂不想升级时&#xff0c;这个小红点就像一个顽固的提醒。 - windowsMac版直接删除更新程序, 有效 cd ~/Library/Google/Googl…

LoRA使用-多个LoRA

LoRA的风格分类 不用去记它有什么很特别的风格&#xff0c;简单来说基础模型就像一个全能画手&#xff0c;什么都能画&#xff0c;而LoRA是在某个风格中经过特训的它的一个分身。使得它更精通该风格。 关于LoR风格分类&#xff1a;提示词撰写公式 Checkpoint&LoRA对比 训…

牛客刷题 — 【排序】[NOIP2012] 国王的游戏(高精度结构体排序)

1.题面&#xff1a;传送门 2. 思路&#xff1a; 相邻的两个大臣的先后顺序只会互相影响&#xff0c;并不会影响其他人的金币数。 假设前 i-1 个人左手上的数乘积为 s 。 ① 若 A 大臣排在B 大臣的前面&#xff0c;则&#xff1a; s 此时的金币数最大值为 。 ② 若B大臣排…

grpc 和限流Sentinel

基于gRPC的微服务通信模块技术方案书 1. 总体架构设计 #mermaid-svg-TiN9cudEfW5mCWHm {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-TiN9cudEfW5mCWHm .error-icon{fill:#552222;}#mermaid-svg-TiN9cudEfW5mCWHm…

经典灰狼算法+编码器+双向长短期记忆神经网络,GWO-Transformer-BiLSTM多变量回归预测,作者:机器学习之心!

经典灰狼算法编码器双向长短期记忆神经网络&#xff0c;GWO-Transformer-BiLSTM多变量回归预测&#xff0c;作者&#xff1a;机器学习之心&#xff01; 目录 经典灰狼算法编码器双向长短期记忆神经网络&#xff0c;GWO-Transformer-BiLSTM多变量回归预测&#xff0c;作者&#…

VGG Image Annotator (VIA):一款免费的数据标注软件介绍与使用

VGG Image Annotator (VIA)&#xff1a;一款免费的数据标注软件介绍与使用 在计算机视觉领域&#xff0c;数据标注是训练机器学习模型的基础步骤之一&#xff0c;而标注工具的选择直接影响标注的效率和准确性。众多标注工具中&#xff0c;VGG Image Annotator (VIA) 是一个开源…

CSS实现百分比水柱图

背景 在echarts没发现有可以直接使用的展示百分比的柱形图,只好自己封装一个组件使用 实现思路 一、图形拆解 要实现的组件是一个 可配置的圆柱形液柱图组件&#xff0c;常用于展示比例进度&#xff0c;比如任务完成度、指标达成率等。把图拆成最小单元然后拼接起来&#x…

详解 rzsz 工具:Windows 与 Linux 文件传输

&#xff08;Linux之软件包管理器&#xff08;CentOS系统&#xff09; —— yum-CSDN博客&#xff09;rzsz工具之前我在这篇文章中介绍过&#xff0c;现在重新详细介绍一下该工具。rzsz 是一个用于在 Windows 和 Linux 系统之间传输文件的工具集&#xff0c;通常通过终端模拟器…

网络编程1(UDP)

网络编程套接字&#xff08;socket api&#xff09; 了解了网络的一些概念&#xff0c;接下来就要进行网络中的跨主机通信&#xff0c;了解网络中的一些API&#xff0c;这里谈到的API都是针对传输层进行的&#xff0c;这是因为我们编写的代码是在应用层&#xff0c;而传输层就…

【电机】定点线性映射

这是一个定点数线性映射的问题&#xff0c;通常用于将浮点型的物理量&#xff08;如速度、位置、扭矩&#xff09;转换为嵌入式系统中使用的整型数据格式&#xff0c;便于通过 CAN 总线或其它通信协议发送给电机控制器。 我们来逐步解析这个过程&#xff0c;并以“速度”为例说…

Spring Cloud 微服务(远程调用与熔断机制深度解析)

&#x1f4cc; 摘要 在微服务架构中&#xff0c;服务之间的远程调用是构建分布式系统的核心环节。然而&#xff0c;随着服务数量的增加和网络复杂度的提升&#xff0c;调用失败、延迟高、异常等问题变得越来越频繁。 为此&#xff0c;Spring Cloud 提供了强大的远程调用组件 …

electron-vite 抽离config.js

1、将config.js 放到resources下的config目录下 module.exports {url: http://192.168.1.17:8000,wsUrl: ws://192.168.1.17:8000, }2、在preload.js 暴露读取API src/preload/index.js(或你的preload入口) const fs require(fs); const path require(path);function getCo…

MySQL Undo Log 深度解析:事务回滚与MVCC的核心功臣

引言 作为MySQL的“数据后悔药”和“历史版本档案馆”&#xff0c;Undo Log&#xff08;回滚日志&#xff09;在事务处理和并发控制中扮演着至关重要的角色。今天咱们就从底层原理出发&#xff0c;结合实际场景&#xff0c;把Undo Log的“里里外外”说个明白&#xff01; 一、…

gin如何返回html

✅ 方法一&#xff1a;直接返回 HTML 字符串 这种方式适合简单场景&#xff0c;比如返回一段固定的 HTML 内容。 package mainimport "github.com/gin-gonic/gin"func main() {r : gin.Default()r.GET("/html", func(c *gin.Context) {htmlContent : <…