首页 > 其他分享 >悬垂引用

悬垂引用

时间:2024-05-15 19:42:08浏览次数:10  
标签:悬垂 thread int cmd 引用 pthread return ptr


int C::RecordDownload(string taskid,string channel, string fileName, int filetype, string begintime, string endtime) { if (fileName == "") { app_log(LOG_DEBUG, "RecordDownload file name error\r\n"); return - 1; } _dhdev_lapi_info* _lapi_info_ptr = GetLapiInfo(_dhdev_comand::_default_cmd); if (_lapi_info_ptr == nullptr) return -1; shared_ptr<_dhdev_cmd_info> _cmd_ptr = InitCommandInfo(_lapi_info_ptr); _cmd_ptr->_lapi_info._cmd_method = "GET"; char _cmd_str_ptr[200] = { 0 }; sprintf(_cmd_str_ptr, "/cgi-bin/loadfile.cgi?action=startLoad&channel=%s&startTime=%s&endTime=%s&subtype=0&Types=dav", channel.c_str(), begintime.c_str(),endtime.c_str()); 。。。。。 //可能对应多个下载过程。所以线程对象也是有多个 pthread_t threadptr; _cmd_ptr->_taskId = taskid; thread_create(&threadptr, DownThreadProc, this);//第一个参数需要一个对象,而不是指针,要有内存位置 { _down_lock_mtx.lock(); DownMap.insert({ taskid, {&threadptr, _cmd_ptr}}); _down_lock_mtx.unlock(); } return 1; } int C::SetDownloadCB(Proxy_DownloadCallback cbFun, void* pUser) { _downCb = cbFun; _pUser = pUser; return 1; } int C::StopRecordDownload(string teskid) { _down_lock_mtx.lock(); pthread_t* tempthread = NULL; std::map<string, std::pair<pthread_t*, std::shared_ptr<_dhdev_cmd_info>>>::iterator it; for (it = DownMap.begin(); it != DownMap.end(); it++) { if (strcmp( (it->first).c_str(), teskid.c_str()) == 0) { it->second.second->_download = false; tempthread = it->second.first; break; } } _down_lock_mtx.unlock(); //等待现成结束,销毁线程 Sleep(2000); if (tempthread) { thread_destroy(*tempthread);//会崩溃;因为线程对象已经没了 tempthread = NULL; } //删除map; _down_lock_mtx.lock(); it->second.first = NULL; it->second.second.reset(); DownMap.erase(it); _down_lock_mtx.unlock(); return 1; } int C::DownThreadProc(void* param) { C* Dhdevptr = (C*)param; std::shared_ptr<_dhdev_cmd_info> _cmd_ptr = nullptr; for (auto it = Dhdevptr->DownMap.begin(); it != Dhdevptr->DownMap.end(); ++it) { if (thread_isself(*(it->second.first)) && it->second.second != nullptr) { _cmd_ptr = it->second.second; break; } } if (_cmd_ptr == nullptr) { return 0; } int _rtn_value = Dhdevptr->SendLapiCommand(_cmd_ptr, nullptr, 0); if (_rtn_value > 0) { if (_cmd_ptr->_response_ptr != nullptr) { if (strstr((char*)_cmd_ptr->_response_ptr, "OK") != nullptr) { return _rtn_value; } } } return _rtn_value; }

线程创建函数:

static inline int thread_create2(pthread_t* thread, unsigned int stacksize, thread_proc func, void* param)
{
#if defined(OS_WINDOWS)
    // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453.aspx
    // CreateThread function: By default, every thread has one megabyte of stack space. 

    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx
    // A thread in an executable that calls the C run-time library (CRT) 
    // should use the _beginthreadex and _endthreadex functions for thread management 
    // rather than CreateThread and ExitThread;

    //thread->handle = CreateThread(NULL, stacksize, (LPTHREAD_START_ROUTINE)func, param, 0, &thread->id);
    typedef unsigned int(__stdcall *thread_routine)(void *);
    thread->handle = (HANDLE)_beginthreadex(NULL, stacksize, (thread_routine)func, param, 0, (unsigned int*)&thread->id);
    return NULL == thread->handle ? -1 : 0;
#else
    // https://linux.die.net/man/3/pthread_create
    // On Linux/x86-32, the default stack size for a new thread is 2 megabytes(10M 64bits)

    // http://udrepper.livejournal.com/20948.html
    // mallopt(M_ARENA_MAX, cpu); // limit multithread virtual memory
    typedef void* (*linux_thread_routine)(void*);
    int r;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, stacksize);
    r = pthread_create(thread, &attr, (linux_thread_routine)func, param);
    pthread_attr_destroy(&attr);
    return r;
#endif
}

 

线程销毁函数

static inline int thread_destroy(pthread_t thread)
{
#if defined(OS_WINDOWS)
    if(thread.id != GetCurrentThreadId())
        WaitForSingleObjectEx(thread.handle, INFINITE, TRUE);
    CloseHandle(thread.handle);
    return 0;
#else
    void* value = NULL;
    if(pthread_equal(pthread_self(),thread))
        return pthread_detach(thread);
    else
        return pthread_join(thread, &value);
#endif
}

 

 再做录像下载功能的时候写了个悬垂引用,导致线程析构崩溃,无效线程句柄

--------https://blog.csdn.net/qq_21438461/article/details/135043382---------------------------------------------------------------------------------

在深入理解C++编程语言的同时,我们也在探索人类如何通过编程抽象地解决问题。悬垂引用(Dangling References)是这种探索的一个关键部分,它们不仅仅是技术问题,也反映了我们在思考和处理信息时可能遇到的挑战。
什么是悬垂引用
悬垂引用发生在引用继续指向一个已经释放或失效的内存地址时。可以把它想象成一个指向不存在目标的指针。就像在现实生活中,如果你试图访问一个已经被拆除的建筑,你会发现自己站在一个空地上,目标不复存在。

int* ptr;
{
    int x = 10;
    ptr = &x;
} // x 的作用域在这里结束
// 现在 ptr 成了一个悬垂指针,因为它指向的内存已经不再有效

悬垂引用主要由于以下几个原因造成:

    局部变量(对象)的引用保存成指针:当函数返回一个局部变量的引用时,该局部变量的生命周期随函数结束而结束,但引用仍然存在。
    对象的作用域结束:当对象的生命周期结束后,任何指向该(局部、临时)对象的引用都会变成悬垂引用。
    动态分配内存的错误管理:如果动态分配的内存被释放或删除,任何指向该内存的引用(指向该内存的指针)都会变悬垂

 

标签:悬垂,thread,int,cmd,引用,pthread,return,ptr
From: https://www.cnblogs.com/8335IT/p/18194532

相关文章

  • 引用开源报表可视化实现数字化转型
    众所周知,现在正是数字化转型的高速发展期。想要实现高效率的办公,就需要引进更为先进的软件平台,实现提质增效的办公效果。低代码技术平台是助力企业提升市场竞争力、扩大市场份额和实现可持续增长的有力武器。如果想了解它带来的好处,可以随时来了解低代码技术平台、开源报表可视化......
  • 使用c#强大的表达式树实现对象的深克隆之解决循环引用的问题
    在上一期博客里,我们提到使用使用c#强大的表达式树实现对象的深克隆,文章地址:https://www.cnblogs.com/gmmy/p/18186750。但是文章里没有解决如何实现循环引用的问题。循环引用在C#中,循环引用通常发生在两个或更多的对象相互持有对方的引用,从而形成一个闭环。这种情况在使用面向对......
  • 使用.net 6.0框架的WPF应用如何引用System.Windows.Forms这个dll
    先说结论:能用.nerfx尽量用fx开发,因为很多坑之前的前辈帮你踩过了。。。解决方法是在这个目录下找到你对应版本的System.Windows.Forms这个dllC:\ProgramFiles\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.26\ref\net6.0这个目录每个人版本不一样,想找到最简单的方法就......
  • LaTeX 常用引用标签前缀
    引用对象标签前缀ChapterchSectionsecSubsectionsecAppendixappFigurefigTabletabListitemitmEquationeqnAlgorithmalg参考:LaTeX交叉引用系统简介......
  • Mybatis中引用类型不需要加@param()注解
    在MyBatis中,对于引用类型的参数(即Java对象),通常不需要使用@Param注解,除非你在映射文件中使用了多个参数,并且这些参数不是封装在一个对象中的。当你只有一个引用类型的参数传递给MyBatis的映射器方法时,MyBatis会自动将该参数作为唯一参数处理,并可以在SQL映射文件中通过......
  • Shell--引用变量带不带""的区别
    在shell脚本中,引用变量时有几种形式: $dir  "$dir"   "${dir}"   ,每种形式的含义不同$dir:这种形式的变量名是最简单的形式,表示直接引用变量的值。在这种情况下,如果变量的值包含空格或特殊字符,则会被解释为单个参数。"$dir": 表示引用变量的值,并保留其中的空格和特殊......
  • 【Java】的四种引用类型
    (一)强引用Java强引用最常见,就是把一个对象赋给一个引用变量,这个引用变量就是强引用,但一个对象被强引用时,它处于可达状态,不会被垃圾回收装置回收,因此强引用是造成内存泄漏的主要原因之一。Strings=newString("ABC");(2)软引用软引用需要SoftReference类来实现,对于只有软引......
  • 第8章 指针和引用
    1什么是指针指针是存储内存地址的变量与所有变量一样,指针也占用内存空间,其特殊之处在于,指针包含的值为内存地址,因此,指针是指向内存单元的特殊变量内存单元通常使用十六进制表示法1.1声明指针和其它变量一样,指针在使用前也需要声明。通常将指针声明为指向特定的类型,如int,......
  • ansible02-ansible变量的定义与引用
    4.1ansible变量的定义与引用playbook中变量的定义变量名只能由数字、字母、下划线组成,且只能由字母开头变量的来源(1)setup模块中的所有变量都可以直接调用(2)在/etc/ansible/hosts中定义- 普通变量:主机组中主机单独定义,优先级高于公共变量- 公共变量:也称组变量,针对主......
  • WPF 引用类库中的图片在设计器的时候显示,运行起来不显示
    我这边是建立了一个类库,然后把所有静态资源放在该类库中,然后主项目添加该项目引用,然后图片死活不显示  1.图片属性设置为资源2.主项目添加该项目引用操作都试过了,就是死活不显示,然后问了别人,让我删除类库重新建一个试试,然后试了下,诶,好像确实可以了,突然想起一个小细节,我......