Linux:线程及其控制

我们已经学了线程的创建,现在要学习线程的控制

线程等待

我们来先写一个没有线程等待的代码:

pthcon.c:

#include<stdio.h>
#include<pthread.h>
void* gopthread(void* arg){while(1){printf("pthread is running\n");sleep(1);}
}
int main(){pthread_t tid;int n=pthread_create(&tid,NULL,gopthread,(void*)"pthread 1");if(n!=0){perror("creat failed\n");return -1;}if(n==0){printf("main thread wait success\n");}return 0;
}

可以看到我们的线程每次运行的结果都是随机的,有时候主线程还没运行完,gopthraed会先运行完;就像在进程中,我们更期望的子进程先运行完,所以我们更希望mian线程后退出

所以线程等待的正确用法:

while :; do ps -aL;sleep 1;done

pthcon.c:

#include<stdio.h>
#include<pthread.h>
void* gopthread(void* arg){int cnt=5;while(cnt--){printf("pthread is running\n");sleep(1);}
}
int main(){pthread_t tid;int n=pthread_create(&tid,NULL,gopthread,(void*)"pthread 1");if(n!=0){perror("creat failed\n");return -1;}n=pthread_join(tid,NULL);printf("maim pthread begin\n");if(n==0){printf("main thread wait success\n");}return 0;
}

#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号

调用pthread_join函数的线程将会一直阻塞,直到我们指定调用的线程(也就是代码里的gopthread)从main中调用pthread_exit、从例程中返回或者被取消,它不停止,main就一直阻塞。如果我们的gopthread从main中返回,那么rval_ptr将包含返回码;如果线程被取消,则由rval_ptr指定的内存单元就被置为PTHREAD_CANCELED

①可以通过调用pthread_join自动把线程置于分离状态,这样资源就可以恢复。如果线程已经处于分离状态,pthread_join调用就会失败,返回EINVAL。

②如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并不获得线程的终止状态。

例如我们调用两次该函数:

#include<stdio.h>
#include<pthread.h>
void* gopthread(void* arg){int cnt=5;while(cnt--){printf("pthread is running\n");sleep(1);}
}
int main(){pthread_t tid;int n=pthread_create(&tid,NULL,gopthread,(void*)"pthread 1");if(n!=0){perror("creat failed\n");return -1;}n=pthread_join(tid,NULL);n=pthread_join(tid,NULL);printf("n==%d\n",n);printf("maim pthread begin\n");if(n==0){printf("main thread wait success\n");}return 0;
}

这时候我们的线程已经处于分离状态,但又调用了一次该函数,所以会报错,3是错误码

pthread_create里第三个参数,我们在前文中提到用结构体,如何把结构体的地址传过去:

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
typedef struct ThreadData{char name[20];int num;
}ThreadData;//定义结构体void* gopthread(void* arg){int cnt=5;while(cnt--){printf("pthread is running\n");sleep(1);}
}
int main(){pthread_t tid;ThreadData *td=(ThreadData*)malloc(sizeof(ThreadData));//防止两个线程同时访问同一片内存,破坏坏主线程的完整性及独立性strcpy(td->name,"thread-1");td->num=1;int n=pthread_create(&tid,NULL,gopthread,(void*)&td);//传参if(n!=0){perror("creat failed\n");return -1;}n=pthread_join(tid,NULL);printf("n==%d\n",n);printf("maim pthread begin\n");if(n==0){printf("main thread wait success\n");}free(td)
;    return 0;
}

集贸,这次我一定要解决你

哦原来是没链接上主机

如果我们想创建多线程呢?

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void*  gopthread(void* args){char* name=(char*)args;while(1){       printf("%s pthread is running\n",name);sleep(1);}return NULL;
}int main(){char names[10][128];pthread_t tids[10];for(int i=1;i<=10;i++){snprintf(names[i],sizeof(names[i]),"thread-%d",i);pthread_create(&tids[i], NULL,gopthread,names[i]);}sleep(1000);return 0;
}

我们发现即使我们按顺序创建线程,但是却不能按顺序调度线程

没事,退出去有顺序就好(加入线程等待)

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void*  gopthread(void* args){char* name=(char*)args;printf("%s pthread is running\n",name);sleep(1);return args;
}int main(){char names[10][128];pthread_t tids[10];for(int i=1;i<=10;i++){snprintf(names[i],sizeof(names[i]),"thread-%d",i);pthread_create(&tids[i], NULL,gopthread,names[i]);}for(int i=1;i<=10;i++){void* name=NULL;pthread_join(tids[i],&name);printf("%s quit...\n",(char*)name);}return 0;
}

我勒个数组越界

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void*  gopthread(void* args){char* name=(char*)args;printf("%s pthread is running\n",name);sleep(1);return args;
}int main(){char names[10][128];pthread_t tids[10];for(int i=0;i<10;i++){snprintf(names[i],sizeof(names[i]),"thread-%d",i);pthread_create(&tids[i], NULL,gopthread,names[i]);}for(int i=0;i<10;i++){void* name=NULL;pthread_join(tids[i],&name);printf("%s quit...\n",(char*)name);}return 0;
}

这下好了

线程终止

main函数结束,main线程结束,也就代表着进程结束了

所以我们得保证其他线程结束的时候,主线程再结束

return通常应用于一个函数的正常终止,exit可以结束整个程序,通常用来在异常情况下立即终止程序

#include <pthread.h>
int pthread_exit(void *rval_ptr);

rval_ptr:是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join函数访问到这个指针。

使用的时候调用这个接口就好了

线程取消

取消线程的前提:线程存在(存在才能被取消)

#include <pthread.h>
int pthread_cancel(pthread_t thread);
Compile and link with -pthread.

取消后线程的返回值是-1

线程分离

join函数是等待线程退出,那么我们可不可以让线程自己退出

答案是线程分离

#include <pthread.h>
int pthread_detach(pthread_t thread);

如果一个线程被创建出来,那么默认他是需要被join的

如果该线程被分离了,那么就不需要被join了

线程可以自己分离自己,也可以由主线程分离,只要存在就可以分离

本函数通常由想让自己脱离的线程使用,就如以下语句:

pthread_detach(pthread_self());

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

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

相关文章

你了解的spring框架有哪些

列举一些重要的Spring模块&#xff1f; Spring Core&#xff1a; 基础,可以说 Spring 其他所有的功能都需要依赖于该类库。主要提供 IOC 依赖注入功能。**Spring Aspects ** &#xff1a; 该模块为与AspectJ的集成提供支持。Spring AOP &#xff1a;提供了面向方面的编程实现。…

【翻译】Qt Designer自定义控件简介

原文链接&#xff1a;Using Custom Widgets with Qt Widgets Designer Qt Designer 可以通过其可扩展的插件机制显示自定义控件&#xff0c;允许用户和第三方扩展定义控件的范围。或者&#xff0c;也可以使用现有的控件作为提供类似 API 的控件类的占位符。 处理自定义控件 尽…

app端文章列表查询-详细教程(上)

app端文章列表查询 一、数据库方面 有关文章的表垂直拆分成了三张表&#xff1a;文章基本信息表&#xff08;字段有文章id、文章作者、文章标题、发布时间等&#xff09;、文章配置表&#xff08;字段有文章id、文章是否可评论、文章可转发、是否已下架、是否已删除等&#x…

STM32CubeIDE(Eclipse)Post-build steps添加带参.exe实现全流程(2):带参调用.exe的几种方法

0 工具准备 STM32CubeIDE工程 带参.exe1 前言 使用STM32CubeIDE编译生成了二进制镜像文件后&#xff0c;有时为了防止镜像被恶意修改&#xff0c;可以通过添加校验和来对整个镜像进行保护&#xff0c;实现手段就是在STM32CubeIDE工程Post-build steps中调用一些外部程序来为镜…

docker配置mysql8报错 ERROR 2002 (HY000)

通过docker启动的mysql&#xff0c;发现navicat无法连接&#xff0c;后来进入容器内部也是无法连接&#xff0c;产生以下错误 root9f3b90339a14:/var/run/mysqld# mysql -u root -p Enter password: ERROR 2002 (HY000): Cant connect to local MySQL server through socket …

【C++、数据结构】二叉排序树(二叉查找树、二叉搜索树)(图解+完整代码)

目录 [⚽1.什么是二叉排序树] [&#x1f3d0;2.构建二叉排序树] [&#x1f3c0;3.二叉排序树的查找操作] [&#x1f94e;4.二叉排序树的删除] [&#x1f3b1;5.完整代码] ⚽1.什么是二叉排序树 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是…

vue3--实现瀑布流-长列表-懒加载

前言 在这一章我们主要学习&#xff1a;瀑布流、长列表、懒加载等功能 瀑布流组件 数据格式 [{"tags": ["all","home","desire","pets"],"_id": "62208123fb7e8b6da85b7dfe","photoLink":…

代码随想录算法训练营Day38 | 62. 不同路径、63. 不同路径 II

目录 62. 不同路径 63. 不同路径 II 62. 不同路径 题目 62. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到…

免费开源的微信开发框架

近年来&#xff0c;随着人工智能技术的快速发展&#xff0c;聊天机器人在各个领域得到了广泛的应用。在社交媒体中&#xff0c;自动回复成为了一个流行的功能&#xff0c;让用户可以方便地与机器人进行互动。gewe框架&#xff0c;一个开源的微信聊天机器人框架&#xff0c;实现…

LeetCode第100题:相同的树

文章目录 &#x1f60a;1.题目&#x1f609;2.解法 &#x1f60a;1.题目 尝试一下该题 &#x1f609;2.解法 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ bool isSameTree…

PeakLight恶意软件活动分析

PeakLight恶意软件 在过去几个月中&#xff0c;PeakLight恶意软件因其通过CDN链接&#xff08;内容交付网络&#xff09;进行的激烈感染活动而备受关注。这种活动负责诱使用户执行编码的命令行或通过伪造的验证码和/或验证门户执行恶意工件。 它旨在通过不同的持久性和规避保护…

【电商项目】1分布式基础篇

1 项目简介 1.2 项目架构图 1.2.1 项目微服务架构图 1.2.2 微服务划分图 2 分布式基础概念 3 Linux系统环境搭建 查看网络IP和网关 linux网络环境配置 补充P123&#xff08;修改linux网络设置&开启root密码访问&#xff09; 设置主机名和hosts映射 主机名解析过程分析&…

S2 引擎-大数据分析表格

一、特性 1&#xff09;开箱即用&#xff1a;提供不同场景下开箱即用的 React, Vue3 表组件及配套分析组件&#xff0c;只需要简单的配置即可轻松实现复杂场景。 2&#xff09;多维交叉分析&#xff1a; 告别单一分析维度&#xff0c;全面拥抱任意维度的自由组合分析。 3&#…

数据脱敏方案总结

什么是数据脱敏 数据脱敏的定义 数据脱敏百度百科中是这样定义的&#xff1a; 数据脱敏&#xff0c;指对某些敏感信息通过脱敏规则进行数据的变形&#xff0c;实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集…

YOLOv11模型改进-注意力-引入简单无参数注意力模块SimAM 提升小目标和遮挡检测

本篇文章将介绍一个新的改进机制——卷积和注意力融合模块SimAM &#xff0c;并阐述如何将其应用于YOLOv11中&#xff0c;显著提升模型性能。首先&#xff0c;SimAM 是一种用于卷积神经网络的简单且无参数的注意力模块&#xff0c;它基于神经科学理论定义能量函数来计算 3-D 注…

若依框架的下载与配置

1. 若依版本 RuoYi-Vue前后端分离版。 2. 框架下载 2.1 后端框架下载 https://gitee.com/y_project/RuoYi-Vue 2.2 前端框架下载 https://github.com/yangzongzhuan/RuoYi-Vue3 3. 数据库配置 3.1 创建数据库 基于MySQL数据库&#xff0c;创建数据库&#xff1a;ry-vu…

Top Down 2D Dojo Chip Set

以下是对这款 2D 微型像素关卡芯片集的简洁介绍&#xff1a; 这是一款基于 8x8 像素网格的 2D 微型像素关卡芯片集&#xff0c;采用经典的像素风格。它包含 66 个.png 格式的芯片&#xff0c;涵盖多种墙壁和门的变体&#xff0c;非常适合用于快速搭建游戏原型的道场关卡。利用…

gazebo显示urdf

最近想要将urdf显示在gazebo中。也就是实现下面这样的效果。 因为我看到网上&#xff0c;很多都是在rviz中显示urdf文件。 <launch><!-- 将 Urdf 文件的内容加载到参数服务器 --><param name"robot_description" textfile"$(find urdf_gazebo)/…

【GAMES101笔记速查——Lecture 17 Materials and Appearances】

目录 1 材质和外观 1.1 自然界中&#xff0c;外观是光线和材质共同作用的结果 1.2 图形学中&#xff0c;什么是材质&#xff1f; 1.2.1 渲染方程严格正确&#xff0c;其中BRDF项决定了物体的材质 1.2.2 漫反射材质 &#xff08;1&#xff09;如何定义漫反射系数&#xff1…

mysql8以上版本第一次下载后的登录问题

mysql8以上版本第一次下载后的登录问题 在官网下载mysql后&#xff0c;按照MySQL下载和安装教程操作就可以 如果出现问题&#xff0c;参考https://blog.csdn.net/weixin_63107823/article/details/136588474 注意ini配置文件&#xff0c;如果你是复制的别人的代码&#xff0…