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

网站做的比较好的公司分销商城加盟

网站做的比较好的公司,分销商城加盟,济宁市兖州区城市建设局网站,中国百强企业1. 问题描述 在一次代码调试的过程中#xff0c;遇到过一个问题#xff0c;线程在调用pthread_cancel时#xff0c;提示未找到目标线程#xff0c;然后程序阻塞在了与目标线程相关的条件变量的释放上#xff0c;造成了死锁的现象。 2. 问题复现 #include pthread.h…1. 问题描述 在一次代码调试的过程中遇到过一个问题线程在调用pthread_cancel时提示未找到目标线程然后程序阻塞在了与目标线程相关的条件变量的释放上造成了死锁的现象。 2. 问题复现 #include pthread.h #include iostream #include unistd.h #include cstring#define BUF_SIZE 8192unsigned char g_buf[BUF_SIZE] {0xff};class Worker { public:Worker() {m_run false;pthread_mutex_init(m_mtx, NULL);pthread_cond_init(m_cond, NULL);pthread_create(m_tid, 0, writeThread, (void*)this);std::cout create thread std::hex std::showbase m_tid std::endl;}~Worker() {pthread_t id pthread_self();std::cout cur thread id std::endl;m_run false;int ret pthread_cancel(m_tid);std::cout ret: ret std::endl;// pthread_join(m_tid, NULL);// Destroy the signalsstd::cout finished 1 std::endl;pthread_cond_destroy(m_cond);std::cout finished 2 std::endl;pthread_mutex_destroy(m_mtx);std::cout finished 3 std::endl;}static void* writeThread(void* obj) {((Worker*)obj)-writeWork();return 0;}void writeWork() {char buf[4096];while(true) {sched_yield();if(!m_run) {memcpy(buf, g_buf, BUF_SIZE);pthread_mutex_lock(m_mtx);while (!m_run){pthread_cond_wait(m_cond, m_mtx);}pthread_mutex_unlock(m_mtx);// write buf}} private:bool m_run{false};pthread_cond_t m_cond;pthread_mutex_t m_mtx;pthread_t m_tid; };int main() {Worker work;// avoid main thread exit before work threadsleep(3);return 0; }程序卡死执行结果如下 打印堆栈信息如下 可以看到主线程阻塞在析构函数中销毁条件变量m_cond的位置而工作线程则阻塞在pthread_cond_wait处等待条件变量的满足。因此看到的现象就如第一张图那样主线程卡死无法完成资源释放。 从pthread_cancel的返回值可以看出工作线程并没有按照预期那样在取消点pthread_cond_wait处被成功释放。返回值3意味着没有找到要取消的线程。 表面原因我们找到了但是根本原因还没有找出来也就是为什么会造成这种结果正常情况下pthread_cancel是不会失败的。猜测一种可能的原因线程的栈空间被其他数据覆盖线程相关信息找不到了。 3. 问题分析与定位 从上图就可以看出0x7ffff6e83700是工作线程该值应该是线程控制信息的地址打印地址内容发现结果为0这就有问题了正常情况下应该是非0值参考当前线程地址的打印信息就可以对比出。所以对该线程的任何操作pthread_cancel、pthread_join都不会正常执行。 知道了原因那就来找找是什么地方导致了这种结果呢猜测是不是赋值操作时数组越界了并且超出了足够大的范围。那么什么操作会有这种结果呢 循环赋值且循环次数足够大通过memcpy、memset、memmove进行赋值且size足够大。 根据以上猜测我们再来看看代码发现在调用memcpy时局部变量buf的大小只有4096而传入的size值确是8192远远超出了buf的大小。将size的大小改为5000后再次执行程序。 可以看到程序正常结束但是5000依然超出了实际内存大小这说明要复现上述问题需要的size值得足够大才行。 实际上通过检测工具可以更方便的check数组越界的情况此处使用gcc自带的工具sanitizers只需要在编译选项中增加-g -fsanitizeaddress选项即可增加调试信息可以更容易定位代码位置。 可以看到该工具定位到可能越界位置在45行代码也就是调用memcpy的位置。 4. 总结 pthread_cancel并不一定保证线程被释放它只是给目标线程发送了一个信号而只有当目标线程到达一个取消点系统调用时目标线程才会退出。如果需要等待线程退出应该调用pthread_join来保证这一点。上述代码中如果在cancel之后调用该函数程序会出现段错误因为在使用线程相关的信息时拿到的是一个空值。在对字符数组进行赋值时c语言提供的一些函数并不安全很多时候越界却不自知。所以我们需要有一些检测工具来帮助我们避免这些情况的发生常用的工具如sanitizers、valgrind等。
http://www.pierceye.com/news/41521/

相关文章:

  • 做网站怎样连数据库wordpress实现用户中心
  • 虚拟主机网站怎么上传文件服务平台app
  • 山东网站备案公司小程序定制公司有哪些
  • 注册网站可以注销嘛甜点网站建设的功能及意义
  • 玉树营销网站建设互联网建网站
  • 扬州电子商务网站建设福建省城乡和住房建设厅网站
  • php做网站项目的思路青岛济南网页设计公司
  • 大学生网站建设心得学校微网站模板下载地址
  • 六安网站开发wordpress安装教程
  • 简述网站制作过程教人做衣服得网站有哪些
  • 制作网站公司首 荐乐云seo公司网站建设浩森宇特
  • 网站建设+设计那种连接线厂家百度地图导航2022最新版下载
  • 网络营销推广与策划第二版答案英文网站首页优化
  • 网站建设三种方法抖音代运营方案计划书
  • ac域名的网站有啥不同建设门户网站申请
  • 就业网站建设总结重庆网址大全
  • 自助网站建设价格公众平台登录
  • 赣州做网站什么价格关键词优化推广公司排名
  • 怎么做网站切图欧洲vodafonewifi18mmpcc
  • 青岛企业网站建设优化有哪些做海岛的网站
  • 电影资源网站建设重庆seo网站推广优化
  • 做赚钱问卷调查的网站烟台开发区建设局网站
  • 怎么把qq空间做成企业网站asp网站过时
  • 连云港市网站建设千图网免费素材图库ppt
  • 苏州网站开发公司兴田德润优惠吗网站域名备案代理
  • 做英文兼职的网站郑州网站建设汉狮
  • 东莞阳光网官方网站登录建筑网站大图
  • 网站做301需要备案吗2023年11月流感
  • 温州网站定制哪家好cms网站怎么做
  • 成都网站建设q479185700棒网站打开不对