当前位置: 首页 > news >正文

linux:线程id及线程互斥

线程的tid不像进程,那不是他真正的id,也不是内核的lwp,而是由pthread库维护的一个唯一值

给用户提供的线程ID,不是内核中的lwp,而是pthread库维护的一个唯一值

库内部也要承担对线程的管理

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void ToHex(pthread_t tid,char*buffer){snprintf(buffer,128,"0x%lx",(unsigned long)tid);
}void* gothread(void* arg){while(1){char buffer[128];ToHex(pthread_self,buffer);printf("arg %s is running\n",buffer);sleep(1);}
}int main(){pthread_t tid;pthread_create(&tid,NULL,gothread,(void*)"thread-1");char buffer[128];ToHex(tid,buffer);printf("new thread tid:%s\n",buffer);pthread_join(tid,NULL);return 0;}

哦,这里报的错是说我的pthread_t的类型可能不匹配,我传回的是pthread_t类型,但是在打印的时候不兼容,可能会被识别为指针对象

当然,也能正常运行

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void ToHex(unsigned long tid,char*buffer){snprintf(buffer,128,"0x%lx",( unsigned long)tid);
}void* gothread(void* arg){while(1){char buffer[128];ToHex((unsigned long)pthread_self,buffer);printf("arg %s is running\n",buffer);sleep(1);}
}int main(){pthread_t tid;pthread_create(&tid,NULL,gothread,(void*)"thread-1");char buffer[128];ToHex((unsigned long)tid,buffer);printf("new thread tid:%s\n",buffer);pthread_join(tid,NULL);return 0;
}

tid在这里就是一个地址

ls /lib/x86_64-linux-gnu/libpthread.so.0 -l

这是Linux系统下的一个线程库

pthread库的本质是一个文件,我们创建进程的时候,本质上是把线程库加载到内存,映射到进程(也就是真实的地址空间)

那么库是如何对线程进行管理的?

就像操作系统对进程的管理一样,struct pthread里存储的是线程在用户级的最基本的属性,线程栈是用户级别的独立栈结构

库对线程进行先描述再组织

在库中创建描述线程的相关结构体字段属性,管理的时候只需要找到对应的线程控制块的地址就可以了

所以Linux下的线程=pthread库中的属性集+LWP

操作系统没有线程,那它势必就要为我们提供LWP的系统调用

大概就像这样:

#define _GNU_SOURCE
#include <sched.h>
int clone(int (*fn)(void *), void *stack, int flags, void *arg, ...
/* pid_t *parent_tid, void *tls, pid_t *child_tid */ );

clone来创建线程(也能创建进程)

封装一个自己的线程库

满屏警告呃呃

把比较严重的处理了一下

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
//创建线程属性的结构体
typedef struct{pthread_t tid;char* name[128];int running;
}Thread;
//线程执行的函数
void gopthread(void* args){Thread* thread=(Thread*)args;while(thread->running){printf("%s is running\n", thread->name);sleep(1);}return NULL;
}
//创建
void mypthread_Create(Thread *threads){threads->running=1;pthread_create(&threads->tid,NULL,gopthread,(void*)threads);//把参数作为结构体传入
}//停止
void mypthread_Stop(Thread *threads){threads->running=0;
}//等待
void mypthread_Join(Thread *threads){pthread_join(threads->tid,NULL);
}int main(){Thread threads[SIZE];//创建线程for(int i=0;i<SIZE;i++){snprintf(threads[i].name,sizeof(threads[i].name),"thread-%d",i+1);mypthread_Create(&threads[i]);}sleep(5);//留给线程运行//停止线程for(int i=0;i<SIZE;i++){mypthread_Stop(&threads[i]);}//等待for(int i=0;i<SIZE;i++){mypthread_Join(&threads[i]);}return 0;
}

线程互斥


http://www.mrgr.cn/news/57336.html

相关文章:

  • Spring Boot技术栈在论坛网站开发中的应用
  • 高效实现Python机器学习:超参数优化中的网格搜索与随机搜索详解
  • Linux杀毒-KVRT
  • Vue组件开发详解
  • 张雪峰:如果你现在是计算机专业,一定要优先报网络安全,它是未来国家发展的大方向
  • 探秘 ArrayList:源码剖析与扩容策略
  • python基础综合案例(数据可视化—折线图可视化)
  • 全栈面试题】模块5-1】Oracle/MySQL 数据库基础
  • Spring Cloud --- Sentinel 规则持久化
  • 前端-基础CSS总结常用
  • 七、数据库服务器(MySQL、PostgreSQL)的搭建
  • 基于Fourier的两个人形机器人:从改进的3D扩散策略之iDP3到从单个RGB视频中模仿学习的OKAMI
  • 【面试经典150】day 6
  • Flutter鸿蒙next 中如何实现 WebView【跳、显、适、反】等一些基础问题
  • 项目太多,拓展固态硬盘,要安装软件如何固定移动硬盘盘符? - 解决必剪本地作品丢失的问题
  • 如何在复杂的信息物理系统中实施风险管理
  • Educational Codeforces Round 170 C New Game
  • sonarqube-代码扫描-1
  • Apache Kyuubi概述——网易数帆(网易杭州研究院)开源
  • C++在实际项目中的应用第一课:游戏开发中的C++
  • segformer的mmcv-full==1.2.7怎么装
  • 软考高级架构师-6.5-NoSQL数据库-超详细讲解+精简总结
  • arp代答观察
  • 驱动开发系列23 - tasklet用法介绍
  • 如何将logism电路转为verilog(一)
  • 【建议收藏】大数据Flink入门专栏-v1.0,配套B站视频教程1小时速通