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

Linux系统编程 day10 接着线程(中期头大,还要写论文)

线程有点懵逼

线程之前函数回顾以及总结部分(对不清楚的问题再思考)

线程控制原语                进程控制原语
pthread_create();          fork();
pthread_self();            getpid();
pthread_exit();            exit();
pthread_join();            wait()/waitpid();
pthread_cancel();          kill();
pthread_detach();

这里写一下昨天的join函数,那块有点难理解。

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>struct thrd{int var ; char str[256];
};void* func(void * arg)
{struct thrd *th; // 这里不能直接使用结构体,因为这是在栈上的th = malloc(sizeof(struct thrd)); // 这边需要在堆区分配内存,如果不使用堆区会发生错误,因为当线程执行完之后,栈上的内存会释放,如果返回栈上的内容会非法访问。th->val = 200;strcpy(th->str , "hello pthread_join");return (void*)th;
}int main(int argc , char* argv[])
{pthread_t tid ; struct thrd *retval;int ret = pthread_create(&tid , NULL , func , NULL);if(ret != 0){fprintf(stderr , "pthread_create error : %s\n" , strerror(ret)); exit(1);   }ret = pthread_join(tid , (void**)&retval);if(ret != 0){fprintf(stderr , "pthread_join error : %s\n" , strerror(ret)); exit(1);   }printf("child thread exit with var = %d , str = %s\n " , retval->val , retval->str);pthread_exit(NULL);}

线程当中用perror没有用,线程会直接返回errno,所以在线程中错误一般使用下面这个格式:

if(ret != 0){fprintf(stderr , "pthread_create error : %s\n" , strerror(ret)); exit(1);   
}

线程分离之后,子线程结束会自动回收,自动清理PCB,无需回收

ret = pthread_detach(tid)

线程属性

初始化线程属性

int pthread_attr_init(pthread_attr_t* attr);
成功返回0
失败errnofprintf(stderr , "pthread_xxx error:%s\n" , strerror(ret));

销毁线程属性所占用的资源 

int pthread_attr_destroy(pthread_attr_t* attr);
成功返回0
失败errno
fprintf(strerr , "pthread_attr_destroy error:%s\n" , strerror(ret));

设置线程分离

int pthread_attr_setdetachstate(pthread_attr_t* attr , int detachstate);参数:attr:已初始化的线程属性
detachstate : PTHREAD_CREATE_DETACHED(分离线程)PTHRED_CREATE_JOINABLE(非分离线程)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>void* tfn(void* arg){printf("thread:pid = %d , tid = %lu\n" , getpid() , pthread_self());return NULL;
}int main(int argc , char *argv[])
{pthread_t tid ;//tid = pthread_self();pthread_attr_t attr;int ret = pthread_attr_init(&attr);if(ret != 0){fprintf(stderr , "pthread_attr_init error:%s/n" , strerror(ret));exit(1);}ret = pthread_attr_setdetachstate(&attr , PTHREAD_CREATE_DETACHED);//设置线>程属性为分离属性if(ret != 0){fprintf(stderr , "pthread_attr_setdetachstate error:%s/n" , strerror(ret));exit(1);}ret = pthread_create(&tid , &attr , tfn , NULL);if(ret != 0){fprintf(stderr , "pthread_create error:%s/n" , strerror(ret));exit(1);}ret = pthread_attr_destroy(&attr);if(ret != 0){fprintf(stderr , "pthread_attr_destory error:%s/n" , strerror(ret));exit(1);}ret = pthread_join(tid , NULL); // 如何查看是否是分离状态,不使用那个函数,>函数太长了,可以使用join函数,如果join函数回收失败出现错误,就表示已经为线程分离
。if(ret != 0){fprintf(stderr , "pthread_join error:%s/n" , strerror(ret));exit(1);}printf("main:pid = %d , tid = %lu\n" , getpid() , pthread_self());pthread_exit(NULL);
}

线程使用注意事项

1、主线程退出其他线程不退出,主线程要使用pthread_exit()。

2、避免僵尸线程。

3、malloc和mmap申请的内存可以被其他线程释放。

4、避免在多线程模型中使用fork,子进程中只有调用fork的线程存在,其余均被退出。

5、信号的复杂语义很难和多线程共存,应避免在多线程引入信号机制。

线程同步

同步:协同,讲究先后次序。

协同步调,对公共区域数据按序访问,防止数据混乱,产生与时间有关的错误。

锁的使用

建议锁,对公共数据进行保护,所有进程应该在访问公共数据之前先拿锁再访问,但锁本身不具备强制性。

互斥锁/互斥量mutex

 使用mutex(互斥量、互斥锁)一般步骤

1、pthread_mutex_t lock;    创建锁
2、pthread_mutex_init();    初始化锁
3、pthread_mutex_lock();    加锁
4、访问共享数据
5、pthread_mutex_unlock();  解锁
6、pthread_mutex_destory(); 销毁锁上述函数成功返回0,失败返回errno

 注意事项:尽量保证锁的粒度

restrict关键字:
用来限定指针变量,被该关键字限定的指针变量所指向的内存操作,必须由本指针完成int pthread_mutex_init(pthread_mutex_t *restrict mutex , const pthread_mutexattr_t *restrict attr);

今天没学完,还要写论文

http://www.xdnf.cn/news/1501.html

相关文章:

  • 钧瓷产业原始创新的许昌共识:技术破壁·产业再造·生态重构(一)
  • C++入门基础知识110—【关于C++嵌套 if 语句】
  • 使用 LangChain 掌握检索增强生成 (RAG) 的终极指南:6、索引
  • Linux:41线程控制lesson29
  • Linux安全防护:全方位服务安全配置指南
  • gem5教程第六章 为ARM扩展gem5 这也是改进gem5的一个基础
  • STM32F103 “BluePill” 上的 DMA 原理与实践
  • 「ES数据迁移可视化工具(Python实现)」支持7.x索引数据互传
  • unity游戏开发之 拖放教程2D
  • 代理ip池有哪些类型?代理IP池的定义、特点与使用场景
  • leetcode0099. 恢复二叉搜索树- medium
  • 在基于Transformer的LLM中,将越重要的提示词前置,对生成效果越好吗
  • LeetCode算法题(Go语言实现)_58
  • 122.在 Vue3 中使用 OpenLayers 实现图层层级控制(zIndex)显示与设置详解
  • CIFAR-10图像分类学习笔记(一)
  • vim的.vimrc配置
  • 【Java面试笔记:基础】11.Java提供了哪些IO方式? NIO如何实现多路复用?
  • 哪些心电图表现无缘事业编体检呢?
  • Linux程序地址空间
  • 【maven-7.1】POM文件中的属性管理:提升构建灵活性与可维护性
  • 《Cesium 中两点绘制线的实现:实线、虚线、动态线、流动线详解》
  • 元素滚动和内容垂直居中同时存在,完美的 html 元素垂直居中的方法flex + margin: auto
  • Java 中 String 转 Integer 的方法与底层原理详解
  • Elasticsearch(ES)中的脚本(Script)
  • 设备沟通不再“鸡同鸭讲”EtherCAT转Profinet网关助力工业互联新升级!
  • SpringMVC从入门到上手-全面讲解SpringMVC的使用.
  • BUUCTF jarvisoj_test_your_memory
  • 电控---DMP库
  • C语言(1)—C语言常见概念
  • xcode 16 遇到contains bitcode