C++ thread的detach函数问题??
#include<iostream>
#include<thread>
using namespace std;
void function_1()
{
    std::cout << "Hello,world!" << std::endl;
}
int main() {
    std::thread t1(function_1);        //t1  starts  running.
    //t1.join();   //main thread waits for t1 finish .等待子线程my_thread执行完之后,主线程才可以继续执行下,此时主线程会释放掉执行完后的子线程资源。
    t1.detach();
    system("pause");
    return 0;
}
```但是执行结果还是会把“Hello,world! ”输出,这是程序哪里出了问题??

6个回答

system("pause");从字面上看好像是让当前程序暂停,但是实际上这个只是调用了一个pause的命令,并且不会让程序暂停。

xq734536013
热爱学习的呆萌的文青 回复caozhy: 我把程序改成win32控制台程序,然后按ctrl F5就可以了,那请问win32控制台程序和普通的程序有什么区别呢?
4 年多之前 回复
xq734536013
热爱学习的呆萌的文青 回复caozhy: 这个明白了,就是如何解决不加system(“pause”)但是使程序执行结果停留不闪退,我按ctrl F5 还是会闪退
4 年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复热爱学习的呆萌的文青: 问题的关键在于,system("pause");不会阻止你的线程输出hello world,明白么?
4 年多之前 回复
xq734536013
热爱学习的呆萌的文青 vs2015编译的,但是如果不加这句的话,程序都会闪退
4 年多之前 回复

哇,请问一下,这个是c++那一个版本的标准函数,我 还不知道能这样写的
c++11还是后序版本?

detach是让线程独立 跟主线程脱离 这样主线程走到pause 而子线程就自己输出字符串等

可以不写system("pause")
你所说的退出原因是你调试了程序,即F5
如果直接运行,即不调试 ctrl+f5 就不会退出了~

您应该再仔细想一想 什么叫多线程~ 然后再搞清楚 detach和join的区别

肯定会输出的,首先你在主程序中启动了一个线程t1,现在程序中存在两个线程一个主线程,一个t1线程;当你调用detach()主线程与t1线程分离,这样他们成为了两个独立的线程遵循cpu的时间片调度分配策略,system("pause")会使主线程暂停,而t1线程肯定还会运行;

xq734536013
热爱学习的呆萌的文青 回复ZMing316: 删除system(“pause”),把.exe拖进cmd运行的界面,却输出了一个H,这是怎么理解呢?
4 年多之前 回复
oTaShanHongYe
ZMing316 不管是调用join还是detach,t1线程都会运行,不同的是join主进程会等待t1进程结束或异常退出,detach不会等待,主进程退出后C++运行时库回收相应的线程资源
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C++ thread的detach函数问题??

``` #include<iostream> #include<thread> using namespace std; void function_1() { std::cout << "Hello,world!" << std::endl; } int main() { std::thread t1(function_1); //t1 starts running. //t1.join(); //main thread waits for t1 finish .等待子线程my_thread执行完之后,主线程才可以继续执行下,此时主线程会释放掉执行完后的子线程资源。 t1.detach(); system("pause"); return 0; } ```但是执行结果还是会把“Hello,world! ”输出,这是程序哪里出了问题??

boost::thread 库在调用join或者detach接口时,会释放系统哪些资源?

#include <boost/thread/thread.hpp> #include <boost/bind.hpp> #include <iostream> #include<boost/function.hpp> ``` class HelloWorld; extern void hello_2(boost::shared_ptr<HelloWorld> he); extern void hello_3(); typedef boost::function<void()> Func_t; class HelloWorld: public boost::enable_shared_from_this<HelloWorld> { public: HelloWorld(std::string name):name_(name),b_(name) { std::cout<<"HelloWorld begin:"<<name_<<std::endl; std::cout<<"HelloWorld end:"<<name_<<std::endl; } ~HelloWorld() { std::cout<<"~HelloWorld begin:"<<name_<<std::endl; //thread_group_.join_all(); sleep(5); std::cout<<"~HelloWorld end:"<<name_<<std::endl; } void hello_1() { std::cout <<"Hello_1 world, I''m a thread!"<< std::endl; sleep(5); std::cout<<"sleep 5s"<<std::endl; } void start() { //boost::shared_ptr<HelloWorld> data_transmitter_ptr = shared_from_this(); //boost::shared_ptr<HelloWorld> hello2(new HelloWorld("submain")); //thread_group_.create_thread( boost::bind(&HelloWorld::hello_1, data_transmitter_ptr) );//进不了HelloWorld析构 //thread_group_.join_all();//可进入HelloWorld析构 //thread_group_.create_thread( boost::bind(&hello_2,hello2) );//可进入HelloWorld析构 //thread_group_.create_thread( boost::bind(&hello_2,data_transmitter_ptr) );//不可进入析构HelloWorld析构 //thread_group_.create_thread( boost::bind(&hello_3) );//可以进入HelloWorld析构 } boost::thread_group thread_group_; std::string name_; }; void hello_2(boost::shared_ptr<HelloWorld> he) { //boost::shared_ptr<HelloWorld> hello2(new HelloWorld()); std::cout <<"Hello_2 world, I''m a thread begin!"<< std::endl; std::cout <<"Hello_2 world, I''m a thread end!"<< std::endl; } void hello_3() { //boost::shared_ptr<HelloWorld> hello2(new HelloWorld()); std::cout <<"Hello_2 world, I''m a thread!"<< std::endl; } int main(int argc, char* argv[]) { { boost::shared_ptr<HelloWorld> hello(new HelloWorld("main")); hello->start(); sleep(3); std::cout<<"sleep 3"<<std::endl; } while(true) { sleep(1); std::cout<<"sleep 1s"<<std::endl; } return 0; } ``` //各位大神,问题如下,急急急: 1.boost::thread或者boost::thread_group,在创建线程时会绑定一个函数对象(暂时记录为FuncA),那什么时候这个函数对象生命周期结束?是join或者detach函数调用之后吗?有没有从源码层大概分析,解释下释放这个FuncA函数对象资源相关参考信息? 2.是否join或者detach不能在本身类似于HelloWorl析构函数中调用,这是个禁忌吗?

c++多线程问题detach和join

c++并发编程实战上说,必须在线程结束前调用detach或者jion。如果线程结束再去分离,会出问题。 我的疑问是这么看来的话,c++根本就没有保证安全啊,即便detach在线程运行后一句就立马调用,也不能保证这是在线程结束前调用的啊,在这一块儿c++11是怎么处理的

C++ 线程和仿函数的问题??

``` #include<iostream> #include<thread> using namespace std; void function_1() { std::cout << "Hello,world!" << std::endl; } class Fctor { //仿函数 public: void operator()() { //对()进行重载 for (int i = 0; i > -100; i--) { cout << "from t1 " << i << endl; } } }; int main() { //Fctor fct; std::thread t1((Fctor())); //t1 starts running. 实例化一个线程对象t1 try { for (int i = 0; i < 100; i++) cout << "from main: " << i << endl; } catch (...) { t1.join(); throw; } t1.join(); //t1.detach(); return 0; } ``` 其中这句 std::thread t1((Fctor())); 为什么要再“Fctor()”两边还要加括号?否则“ t1.join();”这句会提示错误?? 还有能解释下执行结果吗? ![图片说明](https://img-ask.csdn.net/upload/201601/08/1452229227_778741.jpg)

qt std::thread线程如何发送一个信号调用主线程的一个函数

qt按钮下新建了一个线程 std::thread th1(&MainWindow::runTest,this,str_ModelName); th1.detach(); connect(th1,SIGNAL(robotStat(int)),this,SLOT(runTest1(int))); 想要用runtest里面的一个信号,去调用runtest1这个函数, 编译th1不能转为qobject*,请问如何连接

新手求教C++并行代码问题,请大家指点如何实现多个线程的高效计算问题。

如下代码,我分了两个线程计算collision函数,希望两个线程同时进行计算以减少一半的计算时间(双核计算机)。 但是在计算时,由于collision函数运算量过大,后续函数需要用到其计算结果时两个线程都还没计算完成。若将detach()改用join(),则不能提高它的计算速度。请问可以通过什么办法解决上述问题? ``` thread CollisionTest[2];//两个线程 for (int t = 0; t < 2; t++) { CollisionTest[t] = thread(collision, t); CollisionTest[t].detach(); } ```

全局键盘钩子函数的回调函数有时无效

``` DLL代码: myHooke.c #include "myHooke.h" #include <windows.h> #include <winuser.h> #include <stdlib.h> #include <stdio.h> int ndown = 0; HHOOK hhkHook = NULL; //定义钩子句柄 HINSTANCE hInstance = NULL; //程序实例 BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } hInstance = (HINSTANCE)hModule; //得到DLL实例 return TRUE; } //回调函数 __declspec(dllexport) LRESULT CALLBACK myHookProc(int nCode, WPARAM wParam, LPARAM lParam) { LRESULT Result=CallNextHookEx(hhkHook, nCode, wParam, lParam); if(wParam == 'M' && (lParam & 0x40000000)) { printf("M is downed ! %d\n", ndown++); } return Result; } //加载钩子 int load() { if(!(hhkHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)myHookProc, hInstance, 0))) { return FALSE; } return TRUE; } //卸载钩子 int unload() { return UnhookWindowsHookEx(hhkHook); } myHooke.h: #ifndef MYHOOKD_H #define MYHOOKD_H #define EXPORT __declspec(dllexport) #define _WIN32_WINNT 0x400 EXPORT int load(); EXPORT int unload(); #endif 调用的函数: #include <windows.h> #include <winuser.h> #include <stdio.h> #include <stdlib.h> typedef int (*FUNCTION)(); int main(int argc, char *argv[]) { HINSTANCE hDll; FUNCTION loadhook = NULL; FUNCTION unloadhook = NULL; hDll = LoadLibrary("..\\myHooke\\Debug\\myHooke.dll"); if(hDll != NULL) { loadhook = (FUNCTION)GetProcAddress(hDll, "load"); unloadhook = (FUNCTION)GetProcAddress(hDll, "unload"); if(loadhook == NULL) { MessageBox(0, "loadhook failed", "MyHook", MB_OK); return 1; } if(unloadhook == NULL) { MessageBox(0, "unloadhook failed", "MyHook", MB_OK); return 1; } if(!loadhook()) { return 1; } // while(1) { printf("hook is load !"); MessageBox(0, "Hold on box", "MyHook", MB_OK); //使用循环会使程序卡住,所以用了MessageBox是程序暂停 Sleep(1000); } unloadhook(); FreeLibrary(hDll); } return 0; } ``` 有些出口可以获取键盘消息,有些不能获取键盘消息,这是全局钩子,我是菜鸟,求大神帮助啊!!! 补充一下,程序运行时,切换到其他程序,有的可以获取键盘消息,printf有响应;有的没有任何响应,比如切换到网页等; 我想实现的功能是:无论在哪里,只要键盘按下,我的程序就会有响应 打印按键被按下的消息

关于指针BOOL的问题。

使用如下方法创建一个线程 ``` thread GetInf_Result(Translate_Thread, Inf_Send_true); GetInf_Result.detach(); ``` 其中Translate_Thread是线程函数,Inf_Send_true定义: ``` struct Thread_Run_Translate { BOOL *IF; }; Thread_Run_Translate *Inf_Send_true = new Thread_Run_Translate; Inf_Send_true = &IF_Class; ``` IF_Class定义在类中为BOOL类型 在Translate_Thread中判断值,如下: ``` void Translate_Thread(Thread_Run_Translate *Inf) { if(Inf->IF == NULL) //*** } ``` 此时判断有误 求解决办法

win32 sdk钩子函数问题,请大家解决

安装钩子函数不能成功?为什么 我在网上找了,但是没找到解决方法,是我弄错了吗 加载动态链接库能成功,可是安装钩子不能成功?? 这是头文件 hookdll.h ``` #ifndef HOOKDLL_H #define HOOKDLL_H extern "C" bool _declspec(dllexport)EndHook(void); extern "C" bool _declspec(dllexport)StartHook(void); #endif ``` 这是动态链接库文件hookdll.cpp ``` #include "hookdll.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> //#include "hookdll.h" #define MAX 256 #define FILE "c:\\text.txt" HHOOK kg_hHook; HINSTANCE hInstance; bool DataToFile(char* p){ DWORD dWrite = 0; HANDLE hFile = CreateFile(FILE,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); if(hFile == INVALID_HANDLE_VALUE){ printf("CreateFile failed: %d\n",GetLastError()); return false; } if(SetFilePointer(hFile,0,0,FILE_END) == HFILE_ERROR){ printf("SetFilePointer failed: %d\n",GetLastError()); return false; } if(WriteFile(hFile,p,strlen(p),&dWrite,0) == 0){ printf("WriteFile failed: %d\n",GetLastError()); return false; } CloseHandle(hFile); return true; } LRESULT CALLBACK KeyHookProc(int nCode,WPARAM wParam,LPARAM lParam){ if(nCode < 0) return CallNextHookEx(kg_hHook,nCode,wParam,lParam); if(nCode == HC_ACTION){ MSG* pEventMsg = (MSG*)lParam; if(pEventMsg->message == WM_KEYDOWN){ int vKey = pEventMsg->wParam; char ch; char Buff[10]; memset(Buff,0x00,10); const int keyMask = 0x80000000; int iShift = GetKeyState(0x10); int iCapital = GetKeyState(0x14); int iNumLock = GetKeyState(0x96); BOOL bShift = (iShift & keyMask) == keyMask; BOOL bCapital = (iCapital & 1) == 1; BOOL bNumLock = (iNumLock & 1) == 1; if(vKey >= 48 && vKey <= 57){ switch(vKey){ case 48:if(!bShift) ch = '0';else ch = ')';break; case 49:if(!bShift) ch = '1';else ch = '!';break; case 50:if(!bShift) ch = '2';else ch = '@';break; case 51:if(!bShift) ch = '3';else ch = '#';break; case 52:if(!bShift) ch = '4';else ch = '$';break; case 53:if(!bShift) ch = '5';else ch = '%';break; case 54:if(!bShift) ch = '6';else ch = '^';break; case 55:if(!bShift) ch = '7';else ch = '&';break; case 56:if(!bShift) ch = '8';else ch = '*';break; case 57:if(!bShift) ch = '9';else ch = '(';break; } Buff[0] = ch; DataToFile(Buff); } if(vKey >= 65 && vKey <= 90){ if(!bCapital){ if(bShift) ch = vKey; else ch = vKey + 32; } else{ if(bShift) ch = vKey + 32; else ch = vKey; } Buff[0] = ch; DataToFile(Buff); } if(vKey >= 96 && vKey <= 105){ if(bNumLock){ switch(vKey){ case 96: ch = '0';break; case 97: ch = '1';break; case 98: ch = '2';break; case 99: ch = '3';break; case 100:ch = '4';break; case 101:ch = '5';break; case 102:ch = '6';break; case 103:ch = '7';break; case 104:ch = '8';break; case 105:ch = '9';break; } Buff[0] = ch; DataToFile(Buff); } } if(vKey >= 106 && vKey <= 222){ switch(vKey){ case 186:if(!bShift) ch = ';';else ch = ':';break; case 187:if(!bShift) ch = '=';else ch = '+';break; case 188:if(!bShift) ch = ',';else ch = '<';break; case 189:if(!bShift) ch = '-';else ch = '_';break; case 190:if(!bShift) ch = '.';else ch = '>';break; case 191:if(!bShift) ch = '/';else ch = '?';break; case 192:if(!bShift) ch = '`';else ch = '~';break; case 219:if(!bShift) ch = '[';else ch = '{';break; case 220:if(!bShift) ch = '\\';else ch = '|';break; case 221:if(!bShift) ch = ']';else ch = '}';break; case 222:if(!bShift) ch = '\'';else ch = '\"';break; default: break; } Buff[0] = ch; DataToFile(Buff); } switch(vKey){ case 8: strcpy(Buff,"[BK]"); DataToFile(Buff); break; case 13: strcpy(Buff,"[enter]"); DataToFile(Buff); break; default: break; } } } return CallNextHookEx(kg_hHook,nCode,wParam,lParam); } bool StartHook(void){ if(kg_hHook) return false; kg_hHook = SetWindowsHookEx(WH_GETMESSAGE,KeyHookProc,hInstance,NULL); if(kg_hHook) return true; return false; } bool EndHook(void){ if(!kg_hHook) return false; if(UnhookWindowsHookEx(kg_hHook)) return true; return false; } DWORD WINAPI DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpResvered){ hInstance = (HINSTANCE)hModule; switch(ul_reason_for_call){ case DLL_PROCESS_ATTACH: printf("DLL_PROCESS_ATTACH\n"); break; case DLL_PROCESS_DETACH: if(!kg_hHook) UnhookWindowsHookEx(kg_hHook); printf("DLL_PROCESS_DETACH\n"); break; case DLL_THREAD_ATTACH: printf("dll_thread_attach\n"); break; case DLL_THREAD_DETACH: if(!kg_hHook) UnhookWindowsHookEx(kg_hHook); printf("dll_thread_detach\n"); break; default: break; } return true; } ``` 这是调用文件 ``` #include <stdio.h> #include <stdlib.h> #include <windows.h> typedef bool(*starthook)(void); int main(void){ HINSTANCE hDll = LoadLibrary("hookdll.dll"); starthook startHook; if(hDll) startHook = (starthook)GetProcAddress(hDll,"StartHook"); else printf("error\n"); if(!startHook) printf("errpr\n"); else startHook(); return 0; } ``` 困扰了我好久。。。请大家解决

C# 使用 Widgets must be created in the GUI thread

在使用C#调用qt的dll时,第一次调用的一般没事,第二,三次就会出现Widgets must be created in the GUI thread。 这是我用的qt中的代码 BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpvReserved*/ ) { static bool ownApplication = FALSE; if ( dwReason == DLL_PROCESS_ATTACH ) { ownApplication = QMfcApp::pluginInstance( hInstance ); } if ( dwReason == DLL_PROCESS_DETACH && ownApplication ) { delete qApp; } return TRUE; } 这是C#中调用qt的代码 myfun1 = new DLDApi(); myfun1.LoadDll(@"D:\MvcAAA\MvcAAA\bin\meshlab.dll"); // 加载 "Count.dll" myfun1.LoadFun("Test"); // 调入函数 count, "_count@4" 是它的入口,可通过 Depends 查看 object[] Parameters = new object[] { (int)5}; // 实参为 0 Type[] ParameterTypes = new Type[] { typeof(int) }; // 实参类型为 int DLDApi.ModePass[] themode = new DLDApi.ModePass[] { DLDApi.ModePass.ByValue }; // 传送方式为值传 Type Type_Return = typeof(int); // 返回类型为 int // 弹出提示框,显示调用 myfun.Invoke 方法的结果,即调用 count 函数 int i = (int)myfun1.Invoke(Parameters, ParameterTypes, themode, Type_Return); myfun1.UnLoadDll(); C#代码在运行**UnLoadDll**卸载dll方法后,DLL_PROCESS_DETACH中断delete app并没有被执行,整个dll里面有一个qt的线程,卸载了dll后线程并没有被关闭,导致第二次运行的时候无法再次创建QWidegt对象。 想要请教以下各位,如何让在调用完dll后让中的线程关闭掉。是应该写在C++的这个dll中还是写在C#的调用中, 同时这个qt的dll中有一个对象My3Doperation,这个对象继承与QWidget,如何在使用完这个对象后将创建的线程彻底删除。 extern "C" __declspec(dllexport) int Test(int fileName) { My3Doperation model; //计算代码 return fileName+5; }

c++thread设置全局监视键盘事件的未响应问题

int RobotMonitor(int ID) { printf("n线程已启动\"); while (1) { if (GetAsyncKeyState(VK_ESCAPE) && 0x8000) { int sysIO = 10240;//外部暂停 int res = Send_SysIO(sysIO, ID); printf("按下ESC外部暂停\n"); } if (GetAsyncKeyState(VK_CONTROL) && 0x8000) { int errorCode = MovePause(ID); printf("按下CTRL运动指令已暂停\n"); } return 0; } } 这段函数在main中为以下: /*xxxxxxxxxxxxxx线程1:以下为后台detach监控程序xxxxxxxxxxxxxxxx*/ std::thread T1(RobotMonitor,ID); printf("监视线程ID为%i\n", T1.get_id()); T1.detach(); 但是我在程序运行过程中,按esc和ctrl 并没有printf(按下ctrl外部暂停),也无响应,但是printf了“线程已启动”证明已经thread了,为什么按响应按键没有printf响应的语句呢? 是因为线程控制权问题? 线程没有权限在控制台面板输出printf,但是他实际上捕获了键盘操作?

caffe安装过程中boost::未定义问题

各位大神,我在ubuntu16.04中安装caffe,进行到make all的时候报了如下错误: CXX/LD -o .build_release/test/test_all.testbin src/caffe/test/test_caffe_main.cpp .build_release/src/caffe/test/test_benchmark.o:在函数‘void boost::this_thread::sleep<boost::date_time::subsecond_duration<boost::posix_time::time_duration, 1000l> >(boost::date_time::subsecond_duration<boost::posix_time::time_duration, 1000l> const&)’中: test_benchmark.cpp:(.text._ZN5boost11this_thread5sleepINS_9date_time18subsecond_durationINS_10posix_time13time_durationELl1000EEEEEvRKT_[_ZN5boost11this_thread5sleepINS_9date_time18subsecond_durationINS_10posix_time13time_durationELl1000EEEEEvRKT_]+0x25a):对‘boost::this_thread::hidden::sleep_until(timespec const&)’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::thread::start_thread_noexcept()’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::thread::detach()’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::detail::thread_data_base::~thread_data_base()’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::thread::native_handle()’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::thread::interrupt()’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::this_thread::interruption_point()’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::detail::set_tss_data(void const*, boost::shared_ptr<boost::detail::tss_cleanup_function>, void*, bool)’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::thread::interruption_requested() const’未定义的引用 .build_release/lib/libcaffe.so:对‘vtable for boost::detail::thread_data_base’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::detail::get_current_thread_data()’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::thread::joinable() const’未定义的引用 .build_release/lib/libcaffe.so:对‘typeinfo for boost::detail::thread_data_base’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::detail::get_tss_data(void const*)’未定义的引用 .build_release/lib/libcaffe.so:对‘boost::thread::join_noexcept()’未定义的引用 collect2: error: ld returned 1 exit status Makefile:603: recipe for target '.build_release/test/test_all.testbin' failed make: *** [.build_release/test/test_all.testbin] Error 1 一直没有找到有效的解决办法.麻烦遇到过的朋友指点迷津.定重谢!

c++/clr dll工程中,定义一个全局对象,退出dll释放时,atlunadvise返回rpc_e_wrong_thread

环境:c++/clr,引用c# dll 1.一个类CManager,其中定义了一个引用过c# dll的类对象,该对象会调用c#的函数 2.定义一个全局对象CManager g_global,CManager类中创建一个连接点指针 3.CManager的构造函数中,创建了连接点指针atladvise返回值S_OK 4.该dll被一个exe引用,其中函数都正常,现让exe退出 5.在dllmain中,dll detach时,主动调用g_global析构,释放的时候atlunadvise返回rpc_e_wrong_thread, 求大神指点一下,谢谢!

C#程序关闭,进程还在运行

写了一个C#的程序,调用了一个C++的dll,在C++的DLLMain中下面这样写的,特意在DLL_PROCESS_DETACH中关闭了线程,但那个MessageBox在关闭C#程序时并没有弹出来,是不是意味着我所有在dll中开的线程都没关闭?为什么会这样呢? ``` BOOL APIENTRY DllMain( HMODULE hModule, // handle to DLL module DWORD ul_reason_for_call, // reason for calling function LPVOID lpReserved // reserved ) { // Perform actions based on the reason for calling. switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // Initialize once for each new process.Return FALSE to fail DLL load. { SetDllNCCallback(rtm_InterpStartEnd); SendNCDriverUserDecodeEvent(); pctr_dataShm = (LPCTRDATA)malloc(sizeof(Shmctr_data));//初始化全局控制变量 if(pctr_dataShm == NULL) { MessageBox(NULL,TEXT("can not alloc heapmemory in pctr_dataShm"),TEXT("Interpolation Error"),NULL); return 1; } hrtm_PositCtrl_Trd = CreateThread(NULL, 0, rtm_PositCtrl_Trd, NULL,CREATE_SUSPENDED, NULL); SetThreadPriority(hrtm_PositCtrl_Trd, THREAD_PRIORITY_TIME_CRITICAL); ResumeThread(hrtm_PositCtrl_Trd); hrtm_VelCtrl_Trd = CreateThread(NULL, 0, rtm_VelCtrl_Trd, NULL,CREATE_SUSPENDED, NULL); SetThreadPriority(hrtm_VelCtrl_Trd, THREAD_PRIORITY_HIGHEST); ResumeThread(hrtm_VelCtrl_Trd); hrtm_DecodFifo_Trd = CreateThread(NULL, 0, rtm_DecodFifo_Trd, NULL,CREATE_SUSPENDED, NULL); SetThreadPriority(hrtm_DecodFifo_Trd, THREAD_PRIORITY_ABOVE_NORMAL); ResumeThread(hrtm_DecodFifo_Trd); hrtm_Intrp_Trd = CreateThread(NULL, 0, rtm_Intrp_Trd, NULL,CREATE_SUSPENDED, NULL); SetThreadPriority(hrtm_Intrp_Trd, THREAD_PRIORITY_NORMAL); ResumeThread(hrtm_Intrp_Trd); hrtm_Prd_2ms = CreateThread(NULL,0,rtm_Prd_2ms,0,0,NULL); break; } case DLL_THREAD_ATTACH: //MessageBox(NULL,TEXT("Enter DLL_THREAD_ATTACH"),TEXT("Interpolation Inform"),NULL); break; case DLL_THREAD_DETACH: //MessageBox(NULL,TEXT("Enter DLL_THREAD_DETACH"),TEXT("Interpolation Inform"),NULL); break; case DLL_PROCESS_DETACH: CloseHandle(hrtm_PositCtrl_Trd); free(pctr_dataShm); //释放全局控制量 pctr_dataShm = NULL; CloseHandle(hrtm_PositCtrl_Trd); CloseHandle(hrtm_VelCtrl_Trd); CloseHandle(hrtm_DecodFifo_Trd); CloseHandle(hrtm_Intrp_Trd); CloseHandle(hrtm_Prd_2ms); MessageBox(NULL,TEXT("Leave Interpolation dll"),TEXT("Interpolation Inform"),NULL); break; } return TRUE; } ```

利用detours Hook全局API的问题

在下利用微软的detours写了一个Hook全局MessageBox的dll,代码比较短,先贴下,然后再说问题: ``` #include"HookDll.h" #include <detours.h> #pragma comment(lib, "detours.lib") #pragma data_seg("Shared") HHOOK mHook = NULL; HINSTANCE hInstance = NULL; #pragma data_seg() int (WINAPI* OLD_MessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) = MessageBoxW; int (WINAPI* OLD_MessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) = MessageBoxA; //自定义的代替函数 int WINAPI NEW_MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) { int ret = OLD_MessageBoxW(hWnd, L"已经被Hook!", L"Hook", uType); return ret; } int WINAPI NEW_MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { int ret = OLD_MessageBoxA(hWnd, "已经被Hook", "Hook", uType); return ret; } //启动Hook VOID Hook() { DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); //Hook MessageBoxW和MessageBoxA DetourAttach(&(PVOID&)OLD_MessageBoxW, NEW_MessageBoxW); DetourAttach(&(PVOID&)OLD_MessageBoxA, NEW_MessageBoxA); DetourTransactionCommit(); } //撤销Hook VOID UnHook() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); //撤销Hook DetourDetach(&(PVOID&)OLD_MessageBoxW, NEW_MessageBoxW); DetourDetach(&(PVOID&)OLD_MessageBoxA, NEW_MessageBoxA); DetourTransactionCommit(); } //挂钩函数 LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) { return CallNextHookEx(mHook, nCode, wParam, lParam); } //导出函数,安装一个针对WH_CALLWNDPROC的全局钩子 //WH_CALLWNDPROC:当目标线程调用SendMessage发送消息时,钩子函数被调用 extern "C" __declspec(dllexport) BOOL WINAPI Start() { mHook = ::SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, hInstance, 0); return mHook != NULL; } //卸载钩子 extern "C" __declspec(dllexport) void WINAPI Stop() { ::UnhookWindowsHookEx(mHook); } BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH://当DLL被某个进程加载时,执行该case下的语句体 { //在这里干两件事:1.启动Hook,Hook MessageBox // 2.获取本DLL的句柄 //之所以只调用一次Hook,后面解释 static int num = 1; if (1==num) { ++num; Hook(); } hInstance = (HINSTANCE)hModule; break; } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH://当DLL将被卸载时,执行下面的语句体 { //UnHook(); //如果这里加上UnHook(),那MessageBox就不能被Hook了,后面再详述 break; } } return TRUE; } ``` 在下在另一个MFC程序中加载上面的DLL,并且调用Start启动钩子。 按照在下的想法,当一个程序(假设为A)调用SendMessage函数发送消息时,系统会强行将该DLL映射到程序A的地址空间,并且执行case DLL_PROCESS_ATTACH下的语句体,即调用Hook函数,Hook程序A的MessageBox。 但事实是这样的: 在下在另一个C++程序中调用MessageBoxW,发现如下情况: 1.如果在case DLL_PROCESS_DETACH的语句体中加上UnHook调用,那么,无论调用多少次MessageBoxW,没有一次是被Hook的。 2.鉴于1,在下猜想可能是在调用MessageBoxW前就先执行UnHook了,于是干脆就将UnHook注释掉了,这是在调用MessageBoxW,发现,第一次调用没有被Hook,而后面再调用MessageBoxW就被Hook了。但这只是在下写的C++程序的表现,对于其它程序,如记事本,还依然没被Hook。 3.修改上面的DLL,不Hook MessageBox了,而改为Hook CopyFileW和Hook CopyFileA,这时,电脑上的复制粘贴都没有被Hook,自己写程序调用CopyFileW也没有被Hook,但是,在调用CopyFileW前调用一次MessageBoxW,后面的CopyFileW就被Hook了。 综上,在下的理解是:程序的一些行为,如调用MessageBox,才会导致调用SendMessage,进而导致加载DLL,这时才Hook相应的API。 在下想要的效果是:只要我运行一个程序(比如前边的启动钩子的MFC程序),电脑上所有的MessageBox都被Hook了。 在下对Windows消息机制不是特别熟悉,不知道在下的想法有问题还是代码写的有问题,还请诸位大神指点一二。在下先行谢过!

Python 调用C++ dll库文件函数提示WindowsError: exception: access violation writing 0x00905A4D

.H文件如下: /* 视频解码 */ #ifndef __BLL_AUTELVIDEODECODE_H #define __BLL_AUTELVIDEODECODE_H #ifdef AUTELVIDEODECODE_EXPORTS #define AUTELVIDEODECODE_API __declspec(dllexport) #else #define AUTELVIDEODECODE_API __declspec(dllimport) #endif #include "bll/UDPClient/UDPAsyncClient.h" #include "bll/DataManager/DataManager.h" #include "bll/Utils/CommonFuntion.h" #include "bll/frame.h" #include "bll/video_data_mgn.h" #include "bll/h264.h" extern "C" { //编码 #include "libavcodec/avcodec.h" //封装格式处理 #include "libavformat/avformat.h" //像素处理 #include "libswscale/swscale.h" #include "libavutil/avutil.h" #include "libavutil/imgutils.h" }; #pragma comment(lib,"avutil.lib") #pragma comment(lib,"avformat.lib") #pragma comment(lib,"avcodec.lib") #pragma comment(lib,"swscale.lib") #define VIDEO_UDP_PORT (1234) #define min(a, b) ((a) < (b) ? (a) : (b)) #define MAX_RECVBUF_SIZE (64 * 1024) #define MAX_FRAME_SIZE (1024 * 1024) #pragma pack(push, 1) struct Decoder { AVCodec *codec; AVFrame *frame; AVCodecContext *dec_ctx; }; typedef struct { uint8_t *data; int size; int64_t pts; int keyframe; int decode_only; } VideoPacket; typedef struct { int width; int height; int64_t pts; int keyframe; int decode_only; int opaque; uint8_t *data; int size; } YuvFrame; #pragma pack(pop) typedef void (WINAPIV *yuvFrame_func)(YuvFrame *yuv); class AUTELVIDEODECODE_API CAutelVideoDecode { public: explicit CAutelVideoDecode(std::string strHost="", int nPort=VIDEO_UDP_PORT); ~CAutelVideoDecode(void); inline void SetYuvframeCallback(yuvFrame_func pfn) { m_pfnyuvFrame = pfn; } //functions private: //通过udp实时获取视频数据包线程 void StartRecvPacketThread(); void StopRecvPacketThread(); static int WINAPIV recv_video_data_func(char* buf, int length, void* ctx, void* pObj); void DoRecvPacket(); static DWORD ThRecvPacket(LPVOID lpParam); //从buf里面读取视频帧数据进行渲染线程 void StartRenderThread(); void StopRenderThread(); void DoRenderFrame(); static DWORD ThRenderFrame(LPVOID lpParam); Decoder *Decoder_Create(void); int Decoder_Destroy(); int Decoder_Decode(VideoPacket *inpkt, YuvFrame *frame); int get_video_frame(AVFrame *frame, YuvFrame *yuv); void PushFrame(YuvFrame frame); YuvFrame FrontFrame(); //params private: //通过udp实时获取视频数据包线程 HANDLE m_hRecvVideoPacket; bool m_bStopRecvVideoPacket; //从buf里面读取视频帧数据进行渲染线程 HANDLE m_hRenderFrame; bool m_bStopRender; CUDPAsyncClient *m_pUdpClient; std::string m_strHostAddr; int m_udpPort; Decoder *m_pDecoder; yuvFrame_func m_pfnyuvFrame; typedef std::queue<YuvFrame> QUEUE_YUVFRAME; QUEUE_YUVFRAME m_que_yuvframe; CRITICAL_SECTION m_cri_yuvFramequeLocker; }; #endif CPP文件 // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" #include "AutelVideoDecode.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } extern "C" { AUTELVIDEODECODE_API CAutelVideoDecode* AutelVideoDecode() { return new CAutelVideoDecode(); } AUTELVIDEODECODE_API void SetYuvframeCallback(CAutelVideoDecode* pAutel, yuvFrame_func pfn) { pAutel->SetYuvframeCallback(pfn); } } #####编译成AutelVideoDecode.dll库后供python2.7程序调用。 ####Python程序如下 import sys,pygame import YUVFrame import thread from ctypes import * ObjAutelvideodecodeDLL = windll.LoadLibrary(".\\bin\\autelvideodecode.dll") class AutoTestAutelRealTimeVideo: def __init__(self): pygame.init() self.size = width, height = 1280, 720 self.black = 0, 0, 0 self.YUVFrame = None self.overlay =None self.IYUV = pygame.IYUV_OVERLAY self.lock = thread.allocate_lock() CALLFUCTION = CFUNCTYPE(None, POINTER(YUVFrame.YUVFrame)) self.PrenderYuvframe = CALLFUCTION(self.renderYuvframe) #ObjAutelvideodecodeDLL.AutelVideoDecode.argtype=c_char_p ObjAutelvideodecodeDLL.AutelVideoDecode.restype = c_void_p ObjAutelvideodecodeDLL.SetYuvframeCallback.argtypes = (c_void_p,c_void_p) #ObjAutelvideodecodeDLL.SetYuvframeCallback.restype = None self.AutelObj = ObjAutelvideodecodeDLL.AutelVideoDecode() def ...... 编译后出错: Connected to pydev debugger (build 129.782) Traceback (most recent call last): File "C:\Program Files (x86)\JetBrains\PyCharm 2.7.3\helpers\pydev\pydevd.py", line 1481, in <module> debugger.run(setup['file'], None, None) File "C:\Program Files (x86)\JetBrains\PyCharm 2.7.3\helpers\pydev\pydevd.py", line 1124, in run pydev_imports.execfile(file, globals, locals) #execute the script File "E:/AutoTestAutelRealTimeVideo/AutoTestAutelRealTimeVideo.py", line 84, in <module> test() File "E:/AutoTestAutelRealTimeVideo/AutoTestAutelRealTimeVideo.py", line 66, in test test = AutoTestAutelRealTimeVideo() File "E:/AutoTestAutelRealTimeVideo/AutoTestAutelRealTimeVideo.py", line 25, in __init__ self.AutelObj = ObjAutelvideodecodeDLL.AutelVideoDecode() WindowsError: exception: access violation writing 0x00905A4D

CC2540/cc2541关于Watchdog的问题。

最近用CC2540/cc2541做开发,需要设置watchdog,但是在TI的例程里面能够找到它的接口函数,但是不知道是怎么调用的,TI提供的UserGuid里面关于Watchdog的描述也不是很完整。有大神能够提供一些相关的信息或者资料吗? 另外我看到CC2530在PW2模式下Watchdog会自动运行并且自动喂狗,这是怎么实现的?有熟悉的大神能够解答一下吗?

MFC多线程的挂起与启动问题

小弟在MFC多文档下编写的多线程编码,想运行OnThreadResume() 这个函数线程挂起,OnThreadSuspend()开始线程,但为什么调用了OnThreadResume()函数,在调用OnThreadSuspend() 会报错呢,线程的句柄是NULL呢?求解答啊 UINT CDrawView::DrawLine(LPVOID pParam) { PARAM *m_pParam=(PARAM*)pParam; CBrush m_Brush; CWnd m_Wnd; CDC *m_Dc; //根据线程ID产生对应颜色的画刷 if(m_pParam->m_nID==0) { m_Brush.CreateSolidBrush(RGB(255,0,0)); }else if(m_pParam->m_nID==1){ m_Brush.CreateSolidBrush(RGB(0,255,0)); }else{ m_Brush.CreateSolidBrush(RGB(0,0,255)); } //根据窗口句柄,得到CDC m_Wnd.Attach(m_pParam->m_hWnd); m_Dc=m_Wnd.GetDC(); CBrush *m_pOldBrush=(CBrush*)m_Dc->SelectObject(&m_Brush); //重复画矩形,每次前进一个像素 for(int i=1;i<300;i++) { m_Dc->Rectangle(10,35+m_pParam->m_nID*50,10+i,55+m_pParam->m_nID*50); Sleep(100);//让线程暂停100ms,是为了可以明显的看到三个线程是同时执行的 } //(至少我的肉眼看来是这样的,实际并非如此) m_Dc->SelectObject(m_pOldBrush); m_Wnd.Detach(); return 0; } void CDrawView::OnThreadResume() { // TODO: Add your command handler code here CString szContent = "确定要开启线程?"; PARAM *m_pParam[THREAD_NUM]={NULL,NULL,NULL};//传入线种入口函数的参数,初始化为空 CWinThread *m_pThread[THREAD_NUM]; for(int i=0;i<THREAD_NUM;i++){ m_pThread[i]=NULL; m_pParam[i]=new PARAM; memset((void*)m_pParam[i],0,sizeof(PARAM));//将为入口函数参数分配 //的内存全部置0值 //写入线程ID和窗口句柄 m_pParam[i]->m_nID=i; m_pParam[i]->m_hWnd=GetSafeHwnd(); //启动线程 //if(IDYES == MessageBox(szContent,NULL,MB_YESNO)) m_pThread[i]=AfxBeginThread(DrawLine,(LPVOID)(m_pParam[i]),THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); ASSERT(m_pThread[i]); m_pThread[i]->m_bAutoDelete = FALSE; //m_pThread[i]->ResumeThread(); //Sleep(10000); } } void CDrawView::OnThreadSuspend() { // TODO: Add your command handler code here for (int i = 0; i < THREAD_NUM; i ++) { if (m_pThread[i] == NULL) { AfxMessageBox("错误"); } m_pThread[i]->ResumeThread(); } }

C++多线程在执行时,其运行时间比顺序执行时长很多,感觉不合理又找不出原因。请大家解答一下。谢谢。

``` #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <iomanip> #include <math.h> #include <ctime> #include <thread> #include <Windows.h> using namespace std; void main() { double time = 0; double counts = 0; LARGE_INTEGER nFreq; LARGE_INTEGER nBeginTime; LARGE_INTEGER nEndTime; QueryPerformanceFrequency(&nFreq); QueryPerformanceCounter(&nBeginTime);//开始计时 void collision_list_1(); //函数声明 void collision_list_2(); thread collision_test[2];//创建两个线程 collision_test[0] = thread{ collision_list_1}; collision_test[0].detach(); collision_test[1] = thread{ collision_list_2}; collision_test[1].detach(); QueryPerformanceCounter(&nEndTime);//停止计时并输出 time = (double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart; cout << "多线程程序执行时间:" << time * 1000 << "ms" << endl; double time_1 = 0; double counts_1 = 0; LARGE_INTEGER nFreq_1; LARGE_INTEGER nBeginTime_1; LARGE_INTEGER nEndTime_1; QueryPerformanceFrequency(&nFreq_1); QueryPerformanceCounter(&nBeginTime_1);//开始计时 collision_list_1();//顺序执行两个函数 collision_list_2(); QueryPerformanceCounter(&nEndTime_1);//停止计时并输出 time_1 = (double)(nEndTime_1.QuadPart - nBeginTime_1.QuadPart) / (double)nFreq_1.QuadPart; cout << "顺序程序执行时间:" << time_1 * 1000 << "ms" << endl; system("pause"); } void collision_list_1() { for (int i = 0; i < 100000;i++) { int count = 0; count++; } } void collision_list_2() { for (int i = 0; i < 100000; i++) { int count = 0; count++; } } ```

关于Win32核心编程中DLL注入后无反应的解决办法

#include<stdio.h> #include<windows.h> HINSTANCE hProcess; PWSTR pszLibFileRemote; HINSTANCE hThread; void StartInject(int ProcessID, char * DllName); void OverInject(char * DllName); void EnableDebugPrivilege(HANDLE processHandle); int main(int argc, char* argv[]) { int processid = 0; char DllName[50] = "Win32DLL.dll"; while (1) { //ZeroMemory(DllName, sizeof(DllName)); printf("please input the process id:\n"); scanf("%d", &processid); EnableDebugPrivilege(GetCurrentThread()); StartInject(processid, DllName); OverInject(DllName); } return 0; } void StartInject(int ProcessID, char * DllName) { //打开进程,申请访问; hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ProcessID); if (hProcess == NULL) { printf("进程不允许访问!"); getchar(); exit(0); } int cch = 1 + lstrlenW(DllName); int cb = cch * sizeof(WCHAR); pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);//为DllName在远程线程空间分配内存; if (pszLibFileRemote == NULL) { printf("在远程线程空间为DllName分配内存失败!"); getchar(); exit(0); } if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)DllName, cb, NULL)) { printf("在拷贝DllName到远程线程内存地址空间时失败!"); getchar(); exit(0); } /*得到LoadLibraryW在内核(kernel32.dll中的地址)*/ PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"); if (pfnThreadRtn == NULL) { printf("在得到函数地址时出现错误:\n函数名:LoadLibraryW(加载动态链接库)"); getchar(); exit(0); } hThread = CreateRemoteThread(hProcess, NULL, 0,pfnThreadRtn, pszLibFileRemote, 0, NULL); if (hThread == NULL) { printf("创建远程线程失败,错误代码:%d",GetLastError()); getchar(); exit(0); } } void OverInject(char * DllName) { if (DllName != NULL) VirtualFreeEx(hProcess, DllName, 0, MEM_RELEASE); if (hThread != NULL) CloseHandle(hThread); if (hProcess != NULL) CloseHandle(hProcess); } void EnableDebugPrivilege(HANDLE processHandle) { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(processHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { printf("OpenProcessToken"); return; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) { printf("LookupPrivilegeValue"); CloseHandle(hToken); return; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnameValue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) { printf("AdjustTokenPrivileges"); CloseHandle(hToken); } } 然后DLL中是这样的: #include<stdio.h> #include<windows.h> int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: //The DLL is being mapped into the process's address space. MessageBoxW(NULL, "这是一个确定 取消的消息框!", "标题", MB_OKCANCEL); break; case DLL_THREAD_ATTACH: //A thread is being created. break; case DLL_THREAD_DETACH: //A thread is exiting cleanly. break; case DLL_PROCESS_DETACH: //The DLL is being unmapped from the process's address space. break; } /*MessageBoxW(NULL, "这是一个确定 取消的消息框!", "标题", MB_OKCANCEL);*/ return(TRUE); // Used only for DLL_PROCESS_ATTACH }

程序员的兼职技能课

获取讲师答疑方式: 在付费视频第一节(触摸命令_ALL)片头有二维码及加群流程介绍 限时福利 原价99元,今日仅需39元!购课添加小助手(微信号:csdn590)按提示还可领取价值800元的编程大礼包! 讲师介绍: 苏奕嘉&nbsp;前阿里UC项目工程师 脚本开发平台官方认证满级(六级)开发者。 我将如何教会你通过【定制脚本】赚到你人生的第一桶金? 零基础程序定制脚本开发课程,是完全针对零脚本开发经验的小白而设计,课程内容共分为3大阶段: ①前期将带你掌握Q开发语言和界面交互开发能力; ②中期通过实战来制作有具体需求的定制脚本; ③后期将解锁脚本的更高阶玩法,打通任督二脉; ④应用定制脚本合法赚取额外收入的完整经验分享,带你通过程序定制脚本开发这项副业,赚取到你的第一桶金!

Windows版YOLOv4目标检测实战:训练自己的数据集

课程演示环境:Windows10; cuda 10.2; cudnn7.6.5; Python3.7; VisualStudio2019; OpenCV3.4 需要学习ubuntu系统上YOLOv4的同学请前往:《YOLOv4目标检测实战:训练自己的数据集》 课程链接:https://edu.csdn.net/course/detail/28745 YOLOv4来了!速度和精度双提升! 与 YOLOv3 相比,新版本的 AP (精度)和 FPS (每秒帧率)分别提高了 10% 和 12%。 YOLO系列是基于深度学习的端到端实时目标检测方法。本课程将手把手地教大家使用labelImg标注和使用YOLOv4训练自己的数据集。课程实战分为两个项目:单目标检测(足球目标检测)和多目标检测(足球和梅西同时检测)。 本课程的YOLOv4使用AlexyAB/darknet,在Windows系统上做项目演示。包括:安装软件环境、安装YOLOv4、标注自己的数据集、整理自己的数据集、修改配置文件、训练自己的数据集、测试训练出的网络模型、性能统计(mAP计算)和先验框聚类分析。还将介绍改善YOLOv4目标检测性能的技巧。 除本课程《Windows版YOLOv4目标检测实战:训练自己的数据集》外,本人将推出有关YOLOv4目标检测的系列课程。请持续关注该系列的其它视频课程,包括: 《Windows版YOLOv4目标检测实战:人脸口罩佩戴检测》 《Windows版YOLOv4目标检测实战:中国交通标志识别》 《Windows版YOLOv4目标检测:原理与源码解析》

lena全身原图(非256*256版本,而是全身原图)

lena全身原图(非256*256版本,而是全身原图) lena原图很有意思,我们通常所用的256*256图片是在lena原图上截取了头部部分的256*256正方形得到的. 原图是花花公子杂志上的一个

快速入门Android开发 视频 教程 android studio

这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

Java调用微信支付

Java 使用微信支付 一. 准备工作 1.

汽车租赁管理系统需求分析规格说明书

汽车租赁管理系统需求分析规格说明书,这只是一个模板,如果有不会的可以借鉴一下,还是蛮详细的。。。。

C/C++跨平台研发从基础到高阶实战系列套餐

一 专题从基础的C语言核心到c++ 和stl完成基础强化; 二 再到数据结构,设计模式完成专业计算机技能强化; 三 通过跨平台网络编程,linux编程,qt界面编程,mfc编程,windows编程,c++与lua联合编程来完成应用强化 四 最后通过基于ffmpeg的音视频播放器,直播推流,屏幕录像,

程序员的算法通关课:知己知彼(第一季)

【超实用课程内容】 程序员对于算法一直又爱又恨!特别是在求职面试时,算法类问题绝对是不可逃避的提问点!本门课程作为算法面试系列的第一季,会从“知己知彼”的角度,聊聊关于算法面试的那些事~ 【哪些人适合学习这门课程?】 求职中的开发者,对于面试算法阶段缺少经验 想了解实际工作中算法相关知识 在职程序员,算法基础薄弱,急需充电 【超人气讲师】 孙秀洋&nbsp;| 服务器端工程师 硕士毕业于哈工大计算机科学与技术专业,ACM亚洲区赛铜奖获得者,先后在腾讯和百度从事一线技术研发,对算法和后端技术有深刻见解。 【课程如何观看?】 PC端:https://edu.csdn.net/course/detail/27272 移动端:CSDN 学院APP(注意不是CSDN APP哦) 本课程为录播课,课程无限观看时长,但是大家可以抓紧时间学习后一起讨论哦~

机器学习初学者必会的案例精讲

通过六个实际的编码项目,带领同学入门人工智能。这些项目涉及机器学习(回归,分类,聚类),深度学习(神经网络),底层数学算法,Weka数据挖掘,利用Git开源项目实战等。

Python入门视频精讲

Python入门视频培训课程以通俗易懂的方式讲解Python核心技术,Python基础,Python入门。适合初学者的教程,让你少走弯路! 课程内容包括:1.Python简介和安装 、2.第一个Python程序、PyCharm的使用 、3.Python基础、4.函数、5.高级特性、6.面向对象、7.模块、8.异常处理和IO操作、9.访问数据库MySQL。教学全程采用笔记+代码案例的形式讲解,通俗易懂!!!

我以为我对Mysql事务很熟,直到我遇到了阿里面试官

太惨了,面试又被吊打

深度学习原理+项目实战+算法详解+主流框架(套餐)

深度学习系列课程从深度学习基础知识点开始讲解一步步进入神经网络的世界再到卷积和递归神经网络,详解各大经典网络架构。实战部分选择当下最火爆深度学习框架PyTorch与Tensorflow/Keras,全程实战演示框架核心使用与建模方法。项目实战部分选择计算机视觉与自然语言处理领域经典项目,从零开始详解算法原理,debug模式逐行代码解读。适合准备就业和转行的同学们加入学习! 建议按照下列课程顺序来进行学习 (1)掌握深度学习必备经典网络架构 (2)深度框架实战方法 (3)计算机视觉与自然语言处理项目实战。(按照课程排列顺序即可)

Java62数据提取代码

利用苹果手机微信下面的wx.data文件提取出62数据,通过62可以实现不同设备直接登陆,可以通过文件流的方式用脚本上传到服务器进行解析

Python代码实现飞机大战

文章目录经典飞机大战一.游戏设定二.我方飞机三.敌方飞机四.发射子弹五.发放补给包六.主模块 经典飞机大战 源代码以及素材资料(图片,音频)可从下面的github中下载: 飞机大战源代码以及素材资料github项目地址链接 ————————————————————————————————————————————————————————— 不知道大家有没有打过飞机,喜不喜欢打飞机。当我第一次接触这个东西的时候,我的内心是被震撼到的。第一次接触打飞机的时候作者本人是身心愉悦的,因为周边的朋友都在打飞机, 每

2018年全国大学生计算机技能应用大赛决赛 大题

2018年全国大学生计算机技能应用大赛决赛大题,程序填空和程序设计(侵删)

Lena图像处理测试专业用图,高清完整全身原图

Lena图像处理测试专业用图,高清完整全身原图,该图片很好的包含了平坦区域、阴影和纹理等细节,这些都有益于测试各种不同的图像处理算法。它是一幅很好的测试照片!其次,由于这是一个非常有魅力女人的照片。

MySQL数据库面试题(2020最新版)

文章目录数据库基础知识为什么要使用数据库什么是SQL?什么是MySQL?数据库三大范式是什么mysql有关权限的表都有哪几个MySQL的binlog有有几种录入格式?分别有什么区别?数据类型mysql有哪些数据类型引擎MySQL存储引擎MyISAM与InnoDB区别MyISAM索引与InnoDB索引的区别?InnoDB引擎的4大特性存储引擎选择索引什么是索引?索引有哪些优缺点?索引使用场景(重点)...

verilog实现地铁系统售票

使用 verilog 实现地铁售票

Python+OpenCV计算机视觉

Python+OpenCV计算机视觉系统全面的介绍。

Python可以这样学(第四季:数据分析与科学计算可视化)

董付国老师系列教材《Python程序设计(第2版)》(ISBN:9787302436515)、《Python可以这样学》(ISBN:9787302456469)配套视频,在教材基础上又增加了大量内容,通过实例讲解numpy、scipy、pandas、statistics、matplotlib等标准库和扩展库用法。

150讲轻松搞定Python网络爬虫

【为什么学爬虫?】 &nbsp; &nbsp; &nbsp; &nbsp;1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到! &nbsp; &nbsp; &nbsp; &nbsp;2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站 【课程设计】 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: 网络请求:模拟浏览器的行为从网上抓取数据。 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。 &nbsp; 从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! 【课程服务】 专属付费社群+每周三讨论会+1v1答疑

获取Linux下Ftp目录树并逐步绑定到treeview

在linux下抓取目录树,双击后获取该节点子节点(逐步生成)。另外有两个类,一个是windows下的(一次性获取目录树),一个是linux下的(足部获取目录树)

YOLOv3目标检测实战系列课程

《YOLOv3目标检测实战系列课程》旨在帮助大家掌握YOLOv3目标检测的训练、原理、源码与网络模型改进方法。 本课程的YOLOv3使用原作darknet(c语言编写),在Ubuntu系统上做项目演示。 本系列课程包括三门课: (1)《YOLOv3目标检测实战:训练自己的数据集》 包括:安装darknet、给自己的数据集打标签、整理自己的数据集、修改配置文件、训练自己的数据集、测试训练出的网络模型、性能统计(mAP计算和画出PR曲线)和先验框聚类。 (2)《YOLOv3目标检测:原理与源码解析》讲解YOLOv1、YOLOv2、YOLOv3的原理、程序流程并解析各层的源码。 (3)《YOLOv3目标检测:网络模型改进方法》讲解YOLOv3的改进方法,包括改进1:不显示指定类别目标的方法 (增加功能) ;改进2:合并BN层到卷积层 (加快推理速度) ; 改进3:使用GIoU指标和损失函数 (提高检测精度) ;改进4:tiny YOLOv3 (简化网络模型)并介绍 AlexeyAB/darknet项目。

手把手实现Java图书管理系统(附源码)

【超实用课程内容】 本课程演示的是一套基于Java的SSM框架实现的图书管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的java人群。详细介绍了图书管理系统的实现,包括:环境搭建、系统业务、技术实现、项目运行、功能演示、系统扩展等,以通俗易懂的方式,手把手的带你从零开始运行本套图书管理系统,该项目附带全部源码可作为毕设使用。 【课程如何观看?】 PC端:https://edu.csdn.net/course/detail/27513 移动端:CSDN 学院APP(注意不是CSDN APP哦) 本课程为录播课,课程2年有效观看时长,大家可以抓紧时间学习后一起讨论哦~ 【学员专享增值服务】 源码开放 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化

微信小程序开发实战之番茄时钟开发

微信小程序番茄时钟视频教程,本课程将带着各位学员开发一个小程序初级实战类项目,针对只看过官方文档而又无从下手的开发者来说,可以作为一个较好的练手项目,对于有小程序开发经验的开发者而言,可以更好加深对小程序各类组件和API 的理解,为更深层次高难度的项目做铺垫。

Java 最常见的 200+ 面试题:面试必备

这份面试清单是从我 2015 年做了 TeamLeader 之后开始收集的,一方面是给公司招聘用,另一方面是想用它来挖掘在 Java 技术栈中,还有那些知识点是我不知道的,我想找到这些技术盲点,然后修复它,以此来提高自己的技术水平。虽然我是从 2009 年就开始参加编程工作了,但我依旧觉得自己现在要学的东西很多,并且学习这些知识,让我很有成就感和满足感,那所以何乐而不为呢? 说回面试的事,这份面试...

Java基础知识面试题(2020最新版)

文章目录Java概述何为编程什么是Javajdk1.5之后的三大版本JVM、JRE和JDK的关系什么是跨平台性?原理是什么Java语言有哪些特点什么是字节码?采用字节码的最大好处是什么什么是Java程序的主类?应用程序和小程序的主类有何不同?Java应用程序与小程序之间有那些差别?Java和C++的区别Oracle JDK 和 OpenJDK 的对比基础语法数据类型Java有哪些数据类型switc...

三个项目玩转深度学习(附1G源码)

从事大数据与人工智能开发与实践约十年,钱老师亲自见证了大数据行业的发展与人工智能的从冷到热。事实证明,计算机技术的发展,算力突破,海量数据,机器人技术等,开启了第四次工业革命的序章。深度学习图像分类一直是人工智能的经典任务,是智慧零售、安防、无人驾驶等机器视觉应用领域的核心技术之一,掌握图像分类技术是机器视觉学习的重中之重。针对现有线上学习的特点与实际需求,我们开发了人工智能案例实战系列课程。打造:以项目案例实践为驱动的课程学习方式,覆盖了智能零售,智慧交通等常见领域,通过基础学习、项目案例实践、社群答疑,三维立体的方式,打造最好的学习效果。

微信小程序 实例汇总 完整项目源代码

微信小程序 实例汇总 完整项目源代码

基于西门子S7—1200的单部六层电梯设计程序,1部6层电梯

基于西门子S7—1200的单部六层电梯设计程序,1部6层电梯。 本系统控制六层电梯, 采用集选控制方式。 为了完成设定的控制任务, 主要根据电梯输入/输出点数确定PLC 的机型。 根据电梯控制的要求,

相关热词 c#对文件改写权限 c#中tostring c#支付宝回掉 c#转换成数字 c#判断除法是否有模 c# 横向chart c#控件选择多个 c#报表如何锁定表头 c#分级显示数据 c# 不区分大小写替换
立即提问
相关内容推荐