c++多线程问题detach和join

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

4个回答

join 也好 detach 也罢,其实只要在thread对象销毁前调用,就可以了。和线程的运行函数没有关系的。

wkk15903468980
wkk15903468980 茅塞顿开啊,又看了下书,是我搞错了。我把线程对象销毁当成线程结束了
3 年多之前 回复

join就会等待线程执行结束。会阻塞
detach,join的目的就是要你程序, 比如你程序需要退出了,那么最好是等待线程结束,而不是不管线程的执行。

wkk15903468980
wkk15903468980 回复oyljerry: 那书上说的必须在线程结束前调用join怎么解释
3 年多之前 回复
oyljerry
oyljerry 你这个是两个线程啊。当前线程运行到join的时候,如果另一个线程结束了。join就直接返回了。不用租塞。所以逻辑都是对的
3 年多之前 回复
wkk15903468980
wkk15903468980 嗯,正常使用我会,我主要是疑问c++是怎么保证这个detach或join是在线程结束前执行的,好像保证不了啊
3 年多之前 回复
wkk15903468980
wkk15903468980 好像并不是这个样子的啊,我也调试过,线程定义好了就开始运行了,并不是在join处开始~
3 年多之前 回复
feng1790291543
鱼弦 回复wkk15903468980: 你可以调试看看,会执行完join之后,才跑lambda表达式里面的逻辑的
3 年多之前 回复
wkk15903468980
wkk15903468980 用上“资源获取即初始化”方法,我的疑问更加凸显了。在这种方法里,线程启动后会执行他的g函数,那么这段时间里子线程的函数很可能已经运行完了。这之后才去执行析构,去join,不是明摆着犯错误吗?所以这个问题我想不明白啊
3 年多之前 回复

并不需要线程结束前join,线程先结束了,join就会直接返回。你可以看下面代码

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

void fn1()
{
    std::cout << "fn1" << std::endl;
    return;
}

int main() {
    // your code goes here
    std::thread t1(fn1);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    std::cout << "begin join" << std::endl;
    t1.join();
    std::cout << "end join" << std::endl;
    return 0;
}
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
c++多线程问题detach和join

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

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++多线程内存泄漏问题

在主线程用AfxBeginThread开启子线程时,偶尔会报内存泄漏的错误(单线程没问题) 不是频繁报,10次有1~2次的样子,debug我也不知道怎么跟踪,怀疑是锁的问题加上 CCriticalSection cs; cs.Lock();cs.Unlock();后发现还是不行,求助! ``` /*结构体*/ typedef struct _dlgTag { int nIdx; CString strName; } DLGTAG; /*主线程代码*/ //初始化数组 m_Table.clear(); m_Table.swap(vector<vector<CString>>()); m_Table.resize(nLineCount); for (int i = 0; i < nLineCount; i++) { m_Table[i].resize(3); } //遍历 nThreadNum = 0; nThreadAll = 30; for (int i = 0; i < nLineCount; i++) { //多线程工作 if (nThreadNum < nThreadAll) { DLGTAG *dd = new DLGTAG(); dd->nIdx = i; dd->strName = strLine; AfxBeginThread(LoopWorkThread, (LPVOID)dd); nThreadNum++; continue; } //轮巡线程池 while (1) { int nNull = 0, nBegin = i - nThreadAll, nEnd = i; switch (nBegin) { case 0: nBegin++; nEnd++; break; default: break; } for (int j = nBegin; j < nEnd; j++) { if (m_Table[j][1].IsEmpty()) { nNull++; Sleep(100); } } //已完成数 if (nThreadAll - nNull > 0) { nThreadNum = nNull; i--; break; } } } //遍历结束检查线程是否全部执行完毕 while (1) { int nNull = 0, nDone = 0; for (int i = 0; i < nLineCount; i++) { if (m_Table[i][1].IsEmpty()) { nNull++; Sleep(100); } } nDone = nLineCount - nNull; if (nDone >= nLineCount) { break; } } /*子线程LoopWorkThread代码*/ CCriticalSection cs; UINT LoopWorkThread(LPVOID pParam) { DLGTAG* dlg = (DLGTAG*)pParam; CString strFlag = TestTest(dlg->nIdx, dlg->strName); if (strFlag == "成功") { cs.Lock(); m_Table[dlg->nIdx][2] = 业务代码... } m_Table[dlg->nIdx][1] = strFlag; cs.Unlock(); delete dlg; return 0; } ```

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! ”输出,这是程序哪里出了问题??

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++; } } ```

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

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

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++ 多线程, 一读一写, 为什么写线程 无法修改

#include <iostream> #include <unistd.h> #include <thread> uint indx; void wFunc(); void rFunc(); int main(){ indx=0; std::thread *pwthd=new std::thread(wFunc); pwthd->detach(); std::thread *prthd=new std::thread(rFunc); prthd->detach(); sleep(60); } void wFunc(){ uint tmp=indx; while(true){ tmp++; indx=tmp; std::cout<<"w indx:"<<tmp<<std::endl; sleep(1); } } void rFunc(){ uint tmp=indx; while(true){ if(indx>tmp){ tmp=indx; std::cout<<"r indx:"<<tmp<<std::endl; } } }

jquery中detach()和remove()在append方法中的定义

<!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script> $(document).ready(function(){ $("#btn1").click(function(){ $("body").append($("#p1").detach()); }); $("#btn2").click(function(){ $("body").append($("#p2").remove()); }); $("p").click(function(){ $(this).animate({fontSize: "+=1px"}) }); }); </script> </head> <body> 9 <p id="p1"><b>This paragraph will keep its click event even after it is moved.</b></p> <p id="p2">This paragraph will not keep its click event after it is moved.</p> <button id="btn1">Detach and append p element</button> <button id="btn2">Remove and append p element</button> </body> </html> 来自jquery教程的代码入上面所示,我知道detach()意思是删除并缓存 而remove()的意思是删除 可是使用append($("#p1").detach())和append($("#p2").remove())是什么意思啊?

linux多线程的初级问题

#include<stdio.h> #include<stdlib.h> #include<pthread.h> void *test(void *arg); pthread_mutex_t mutex; int main() { pthread_t t_id; for(int i=0;i<50;i++) { pthread_create(&t_id,NULL,test,(void*)&i); } pthread_mutex_destroy(&mutex); } void *test(void *arg) { pthread_detach(pthread_self()); int i=*(int*)arg; printf("%d:\n",i); return NULL; } 请前辈看看这段代码,为什么输出会有重复的数字,有时候输出数量还会少于50,当把pthread_detach()换为pthread_join()的时候就很正常了,求解答。

您可以在Golang中使用SQLite ATTACH和DETACH吗

<div class="post-text" itemprop="text"> <p>I am using <a href="https://github.com/mattn/go-sqlite3" rel="nofollow">https://github.com/mattn/go-sqlite3</a> in a Golang application. I need to use multiple databases, and was wondering whether I can use ATTACH and DETACH in Golang (<a href="http://sqlite.org/lang_attach.html" rel="nofollow">http://sqlite.org/lang_attach.html</a>).</p> <p>I don't have any code right now, because I don't know how else to tackle this problem except creating two database connections and joining data in the application:</p> <pre><code>db1, err := sql.Open("sqlite3", "./db1.db") db2, err := sql.Open("sqlite3", "./db2.db") // query db1 and db2 // put into map // join data </code></pre> <p>It would be much easier if you could use:</p> <pre><code>attach database database1.db as db1; attach database database2.db as db2; select * from db1.SomeTable a inner join db2.SomeTable b on b.SomeColumn = a.SomeColumn; </code></pre> </div>

线程 第一次创建返回11,已经在子线程·加了detach(贴一部分相关的,计算机网络实验)

while(true) { int ret = pthread_create(&t1,NULL,th,(void*)&listen1); /*bind(listen1, (SOCKADDR *)&myaddr, sizeof(myaddr)); listen(listen1, 5);*/ if(ret!=0) { printf("create error:%d\n",ret); exit(1); } pthread_cancel(t1);//等待线程退出 } void* th(void *arg) { pthread_detach(pthread_self()); SOCKET acce ; SOCKET *listen1 = (SOCKET*) arg; SOCKADDR_IN friaddr1; memset(&friaddr1, 0, sizeof(friaddr1)); int friaddr1Len = sizeof(friaddr1); acce = accept(*listen1,(SOCKADDR *)&friaddr1, &friaddr1Len); char fmessage[100]={0}; char textdata2[100]={0}; recv(acce,fmessage, sizeof(fmessage), 0); printf("%s+3\n",fmessage); send(acce, textdata2, strlen(textdata2)+1, 0); printf("%s+4\n",textdata2); pthread_exit(NULL); return 0; }

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)

Laravel - 在attach()和detach()之后检查查询执行

<div class="post-text" itemprop="text"> <p>After I execute this</p> <pre><code>$shop-&gt;articles()-&gt;attach($article_id); </code></pre> <p>or this</p> <pre><code>$shop-&gt;articles()-&gt;detach($article_id); </code></pre> <p>how do I make sure they actually get executed? In the first case it returns void, but also it saves automatically so I cannot use the save function to check it. In the second case it returns int, but what does it represent?</p> </div>

pthread_create后子线程输出了两次

#include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <pthread.h> void *start_handler(void *); int main(void) { pthread_t tid; int err; if(err = pthread_create(&tid, NULL, start_handler, NULL)) { fprintf(stderr, "Create thread: %s\n", strerror(err)); return -1; } printf("OK\n"); return 0; } void *start_handler(void *arg) { int err; if(err = pthread_detach(pthread_self())) { fprintf(stderr, "Detach thread: %s\n", strerror(err)); pthread_exit((void *)-1); } printf("Start!\n"); pthread_exit((void *)1); }

关于在控制台中弹出窗体的问题,可能要用到多线程

现在我已经实现了通过控制台输入来弹出一个窗体,如图所示。但是我想在控制台不关闭的情况下,继续输入并继续弹出窗体,应该如何实现呢?请大神赐教!![图片说明](https://img-ask.csdn.net/upload/201708/18/1503017155_302410.png) 代码: #include <iostream> #include<thread> #include "windows.h" #pragma once #include "Duilib/UIlib.h" using namespace DuiLib; using namespace std; #ifdef _DEBUG # ifdef _UNICODE # pragma comment(lib, "bin\\DuiLib_ud.lib") # else # pragma comment(lib, "bin\\DuiLib_d.lib") # endif #else # ifdef _UNICODE # pragma comment(lib, "bin\\DuiLib_u.lib") # else # pragma comment(lib, "bin\\DuiLib.lib") # endif #endif //DWORD WINAPI funproc(LPVOID lpparentet); //int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow); //void WINAPI t1(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow); /*DWORD WINAPI funproc(LPVOID lpparentet) { Sleep(1000); cout << "子线程线程!" << endl; return 0; }*/ class CDuiFrameWnd : public CWindowWnd, public INotifyUI { public: virtual LPCTSTR GetWindowClassName() const { return _T("DUIMainFrame"); } virtual void Notify(TNotifyUI& msg) { if (msg.sType == _T("click")) { if (msg.pSender->GetName() == _T("button1")) { ::MessageBox(NULL, _T("我是按钮test1"), _T("点击了test1"), NULL); } if (msg.pSender->GetName() == _T("button2")) { ::MessageBox(NULL, _T("我是按钮test2"), _T("点击了test2"), NULL); } } } virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes = 0; if (uMsg == WM_CREATE) { m_PaintManager.Init(m_hWnd); CDialogBuilder builder; CControlUI* pRoot = builder.Create(_T("XMLFILE.xml"), (UINT)0, NULL, &m_PaintManager); // duilib.xml需要放到exe目录下 ASSERT(pRoot && "Failed to parse XML"); m_PaintManager.AttachDialog(pRoot); m_PaintManager.AddNotifier(this); // 添加控件等消息响应,这样消息就会传达到duilib的消息循环,我们可以在Notify函数里做消息处理 return lRes; } if (m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes)) { return lRes; } return __super::HandleMessage(uMsg, wParam, lParam); } protected: CPaintManagerUI m_PaintManager; }; int main() { int i; CDuiFrameWnd duiFrame; //HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); cout << "输入1弹出窗体" << endl; cin >> i; while (i == 1) { std::thread t1([&]() { HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); CPaintManagerUI::SetInstance(hInstance); CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); duiFrame.Create(NULL, _T("cyq"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE); duiFrame.CenterWindow(); duiFrame.ShowModal(); }); t1.detach(); cin >> i; } cout << "wrong number!"; system("pause"); return 0; }

C++ 怎样回收线程,。。。

我想实现一个线程池。想到这样一个问题,一个线程被创建以后自动运行,运行结束后自动释放。 比如下面代码中的t运行结束后就释放掉了。那么怎样实现对一个线程的二次使用呢,就比如下面的t运行一次后不要自动释放,重新回收后可以为我执行别的任务。 void fun() { cout<<"thread"<<endl ; } void main() { thread t(fun) ; t.detach() ; //t.join(); return ; }

关于pthread_mutex多个线程忙等待问题?

文档说如果对一个已加锁的mutex再次加锁pthread_mutex_lock会形成一个等待队列。可是这个示例有点奇怪,我知道线程没有放弃cpu,可是为什么后面输出的hello不到数量? ``` #ifndef THREAD_POOL_H #define THREAD_POOL_H #include <pthread.h> #include <errno.h> #include <iostream> #include <unistd.h> #include <queue> class sample { public: void process(); }; template <typename T> class threadPool { public: threadPool(); void append(T &s); static void *worker(void *s); private: std::queue<T *> tasks; pthread_t threads[5]; bool run = true; pthread_mutex_t t; }; // template <typename T> // void threadPool<T>::append(T& s) // { // pthread_t t; // pthread_create(&t,nullptr,worker,&s); // pthread_detach(t); // } template <typename T> threadPool<T>::threadPool() : tasks() { pthread_mutex_init(&t,nullptr); for(int i=0;i<5;++i) { pthread_create(&threads[i],nullptr,worker,this); pthread_detach(threads[i]); } } template <typename T> void threadPool<T>::append(T &s) { pthread_mutex_lock(&t); tasks.push(&s); printf("%d append.\n",pthread_self()); pthread_mutex_unlock(&t); } template <typename T> void *threadPool<T>::worker(void *s) { auto pool=static_cast<threadPool<T>*>(s); while (pool->run) { pthread_mutex_lock(&(pool->t)); if (pool->tasks.empty()) { pthread_mutex_unlock(&(pool->t)); printf("%d get the lock but continue.\n",pthread_self()); continue; } auto work = pool->tasks.front(); pool->tasks.pop(); printf("%d get the lock and print\n",pthread_self()); pthread_mutex_unlock(&(pool->t)); work->process(); } return nullptr; } #endif //!THREAD_POOL_H ``` ``` #include "thread_pool.h" void sample::process() { std::cout<<"hello world.\n"<<std::endl; } ``` ``` #include "thread_pool.h" #include <iostream> int main(int argc, char **argv) { threadPool<sample> pool; sample d[100]; for(int i=0;i<100;++i) { pool.append(d[i]); } return 0; } ``` ``` 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1268307712 get the lock but continue. 1285158720 append. 1268307712 get the lock and print 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1243129600 get the lock but continue. 1259915008 get the lock but continue. 1251522304 get the lock but continue. hello world. 1285158720 append. 1268307712 get the lock and print hello world. 1268307712 get the lock but continue. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1251522304 get the lock and print hello world. 1251522304 get the lock and print hello world. 1259915008 get the lock and print 1243129600 get the lock and print hello world. 1243129600 get the lock and print hello world. 1243129600 get the lock and print hello world. 1243129600 get the lock and print hello world. 1243129600 get the lock and print hello world. 1285158720 append. 1251522304 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1285158720 append. 1234736896 get the lock and print hello world. 1259915008 get the lock and print hello world. 1259915008 get the lock and print hello world. 1259915008 get the lock and print hello world. hello world. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1251522304 get the lock and print hello world. 1251522304 get the lock and print hello world. 1251522304 get the lock and print hello world. 1251522304 get the lock and print hello world. 1251522304 get the lock and print hello world. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1251522304 get the lock but continue. 1268307712 get the lock but continue. 1259915008 get the lock but continue. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1234736896 get the lock and print hello world. 1234736896 get the lock and print hello world. 1243129600 get the lock and print hello world. 1243129600 get the lock and print hello world. 1243129600 get the lock and print hello world. 1243129600 get the lock and print hello world. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1243129600 get the lock but continue. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. 1285158720 append. ``` **头晕了一下午,麻烦大佬出来解救众生。**

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,但是他实际上捕获了键盘操作?

laravel sync和detach不能用于删除所有实例

<div class="post-text" itemprop="text"> <p>I'm working on a project where users can work on multiple projects and projects can have multiple users working on it. With this project I am using the sync method to add and delete instances in the pivot table. Whenever I am using sync with an empty array or detach to delete all instances that have a certain project id, it doesn't work and the instances keep existing.</p> <p>While the sync with parameters work to add data to the database I find it very strange that deleting wont work. Same with a sync on only one instance while there are more instances in the database, it will delete the other instances and keep the one.</p> <p>My function:</p> <pre><code>public function update(CreateProjectRequest $request) { if($request-&gt;get('contribute')) { foreach($request-&gt;get('contribute') as $k =&gt; $contribute) { if($contribute == 1) { $this-&gt;project = $this-&gt;project-&gt;find($request-&gt;project_id); $keys[] = $k; } } } if(isset($keys)) { $this-&gt;project-&gt;users()-&gt;sync($keys); } else { </code></pre> <blockquote> <p>$this-&gt;project-&gt;users()-&gt;detach();</p> </blockquote> <pre><code> } $this-&gt;project = $this-&gt;project-&gt;find($request-&gt;project_id); $this-&gt;project-&gt;fill($request-&gt;input())-&gt;save(); return redirect('project'); } </code></pre> </div>

在中国程序员是青春饭吗?

今年,我也32了 ,为了不给大家误导,咨询了猎头、圈内好友,以及年过35岁的几位老程序员……舍了老脸去揭人家伤疤……希望能给大家以帮助,记得帮我点赞哦。 目录: 你以为的人生 一次又一次的伤害 猎头界的真相 如何应对互联网行业的「中年危机」 一、你以为的人生 刚入行时,拿着傲人的工资,想着好好干,以为我们的人生是这样的: 等真到了那一天,你会发现,你的人生很可能是这样的: ...

程序员请照顾好自己,周末病魔差点一套带走我。

程序员在一个周末的时间,得了重病,差点当场去世,还好及时挽救回来了。

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

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

和黑客斗争的 6 天!

互联网公司工作,很难避免不和黑客们打交道,我呆过的两家互联网公司,几乎每月每天每分钟都有黑客在公司网站上扫描。有的是寻找 Sql 注入的缺口,有的是寻找线上服务器可能存在的漏洞,大部分都...

Intellij IDEA 实用插件安利

1. 前言从2020 年 JVM 生态报告解读 可以看出Intellij IDEA 目前已经稳坐 Java IDE 头把交椅。而且统计得出付费用户已经超过了八成(国外统计)。IDEA 的...

搜狗输入法也在挑战国人的智商!

故事总是一个接着一个到来...上周写完《鲁大师已经彻底沦为一款垃圾流氓软件!》这篇文章之后,鲁大师的市场工作人员就找到了我,希望把这篇文章删除掉。经过一番沟通我先把这篇文章从公号中删除了...

总结了 150 余个神奇网站,你不来瞅瞅吗?

原博客再更新,可能就没了,之后将持续更新本篇博客。

副业收入是我做程序媛的3倍,工作外的B面人生是怎样的?

提到“程序员”,多数人脑海里首先想到的大约是:为人木讷、薪水超高、工作枯燥…… 然而,当离开工作岗位,撕去层层标签,脱下“程序员”这身外套,有的人生动又有趣,马上展现出了完全不同的A/B面人生! 不论是简单的爱好,还是正经的副业,他们都干得同样出色。偶尔,还能和程序员的特质结合,产生奇妙的“化学反应”。 @Charlotte:平日素颜示人,周末美妆博主 大家都以为程序媛也个个不修边幅,但我们也许...

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

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

如果你是老板,你会不会踢了这样的员工?

有个好朋友ZS,是技术总监,昨天问我:“有一个老下属,跟了我很多年,做事勤勤恳恳,主动性也很好。但随着公司的发展,他的进步速度,跟不上团队的步伐了,有点...

我入职阿里后,才知道原来简历这么写

私下里,有不少读者问我:“二哥,如何才能写出一份专业的技术简历呢?我总感觉自己写的简历太烂了,所以投了无数份,都石沉大海了。”说实话,我自己好多年没有写过简历了,但我认识的一个同行,他在阿里,给我说了一些他当年写简历的方法论,我感觉太牛逼了,实在是忍不住,就分享了出来,希望能够帮助到你。 01、简历的本质 作为简历的撰写者,你必须要搞清楚一点,简历的本质是什么,它就是为了来销售你的价值主张的。往深...

魂迁光刻,梦绕芯片,中芯国际终获ASML大型光刻机

据羊城晚报报道,近日中芯国际从荷兰进口的一台大型光刻机,顺利通过深圳出口加工区场站两道闸口进入厂区,中芯国际发表公告称该光刻机并非此前盛传的EUV光刻机,主要用于企业复工复产后的生产线扩容。 我们知道EUV主要用于7nm及以下制程的芯片制造,光刻机作为集成电路制造中最关键的设备,对芯片制作工艺有着决定性的影响,被誉为“超精密制造技术皇冠上的明珠”,根据之前中芯国际的公报,目...

优雅的替换if-else语句

场景 日常开发,if-else语句写的不少吧??当逻辑分支非常多的时候,if-else套了一层又一层,虽然业务功能倒是实现了,但是看起来是真的很不优雅,尤其是对于我这种有强迫症的程序"猿",看到这么多if-else,脑袋瓜子就嗡嗡的,总想着解锁新姿势:干掉过多的if-else!!!本文将介绍三板斧手段: 优先判断条件,条件不满足的,逻辑及时中断返回; 采用策略模式+工厂模式; 结合注解,锦...

离职半年了,老东家又发 offer,回不回?

有小伙伴问松哥这个问题,他在上海某公司,在离职了几个月后,前公司的领导联系到他,希望他能够返聘回去,他很纠结要不要回去? 俗话说好马不吃回头草,但是这个小伙伴既然感到纠结了,我觉得至少说明了两个问题:1.曾经的公司还不错;2.现在的日子也不是很如意。否则应该就不会纠结了。 老实说,松哥之前也有过类似的经历,今天就来和小伙伴们聊聊回头草到底吃不吃。 首先一个基本观点,就是离职了也没必要和老东家弄的苦...

2020阿里全球数学大赛:3万名高手、4道题、2天2夜未交卷

阿里巴巴全球数学竞赛( Alibaba Global Mathematics Competition)由马云发起,由中国科学技术协会、阿里巴巴基金会、阿里巴巴达摩院共同举办。大赛不设报名门槛,全世界爱好数学的人都可参与,不论是否出身数学专业、是否投身数学研究。 2020年阿里巴巴达摩院邀请北京大学、剑桥大学、浙江大学等高校的顶尖数学教师组建了出题组。中科院院士、美国艺术与科学院院士、北京国际数学...

为什么你不想学习?只想玩?人是如何一步一步废掉的

不知道是不是只有我这样子,还是你们也有过类似的经历。 上学的时候总有很多光辉历史,学年名列前茅,或者单科目大佬,但是虽然慢慢地长大了,你开始懈怠了,开始废掉了。。。 什么?你说不知道具体的情况是怎么样的? 我来告诉你: 你常常潜意识里或者心理觉得,自己真正的生活或者奋斗还没有开始。总是幻想着自己还拥有大把时间,还有无限的可能,自己还能逆风翻盘,只不是自己还没开始罢了,自己以后肯定会变得特别厉害...

百度工程师,获利10万,判刑3年!

所有一夜暴富的方法都写在刑法中,但总有人心存侥幸。这些年互联网犯罪高发,一些工程师高技术犯罪更是引发关注。这两天,一个百度运维工程师的案例传遍朋友圈。1...

程序员为什么千万不要瞎努力?

本文作者用对比非常鲜明的两个开发团队的故事,讲解了敏捷开发之道 —— 如果你的团队缺乏统一标准的环境,那么即使勤劳努力,不仅会极其耗时而且成果甚微,使用...

为什么程序员做外包会被瞧不起?

二哥,有个事想询问下您的意见,您觉得应届生值得去外包吗?公司虽然挺大的,中xx,但待遇感觉挺低,马上要报到,挺纠结的。

当HR压你价,说你只值7K,你该怎么回答?

当HR压你价,说你只值7K时,你可以流畅地回答,记住,是流畅,不能犹豫。 礼貌地说:“7K是吗?了解了。嗯~其实我对贵司的面试官印象很好。只不过,现在我的手头上已经有一份11K的offer。来面试,主要也是自己对贵司挺有兴趣的,所以过来看看……”(未完) 这段话主要是陪HR互诈的同时,从公司兴趣,公司职员印象上,都给予对方正面的肯定,既能提升HR的好感度,又能让谈判气氛融洽,为后面的发挥留足空间。...

面试:第十六章:Java中级开发(16k)

HashMap底层实现原理,红黑树,B+树,B树的结构原理 Spring的AOP和IOC是什么?它们常见的使用场景有哪些?Spring事务,事务的属性,传播行为,数据库隔离级别 Spring和SpringMVC,MyBatis以及SpringBoot的注解分别有哪些?SpringMVC的工作原理,SpringBoot框架的优点,MyBatis框架的优点 SpringCould组件有哪些,他们...

面试阿里p7,被按在地上摩擦,鬼知道我经历了什么?

面试阿里p7被问到的问题(当时我只知道第一个):@Conditional是做什么的?@Conditional多个条件是什么逻辑关系?条件判断在什么时候执...

无代码时代来临,程序员如何保住饭碗?

编程语言层出不穷,从最初的机器语言到如今2500种以上的高级语言,程序员们大呼“学到头秃”。程序员一边面临编程语言不断推陈出新,一边面临由于许多代码已存在,程序员编写新应用程序时存在重复“搬砖”的现象。 无代码/低代码编程应运而生。无代码/低代码是一种创建应用的方法,它可以让开发者使用最少的编码知识来快速开发应用程序。开发者通过图形界面中,可视化建模来组装和配置应用程序。这样一来,开发者直...

面试了一个 31 岁程序员,让我有所触动,30岁以上的程序员该何去何从?

最近面试了一个31岁8年经验的程序猿,让我有点感慨,大龄程序猿该何去何从。

大三实习生,字节跳动面经分享,已拿Offer

说实话,自己的算法,我一个不会,太难了吧

程序员垃圾简历长什么样?

已经连续五年参加大厂校招、社招的技术面试工作,简历看的不下于万份 这篇文章会用实例告诉你,什么是差的程序员简历! 疫情快要结束了,各个公司也都开始春招了,作为即将红遍大江南北的新晋UP主,那当然要为小伙伴们做点事(手动狗头)。 就在公众号里公开征简历,义务帮大家看,并一一点评。《启舰:春招在即,义务帮大家看看简历吧》 一石激起千层浪,三天收到两百多封简历。 花光了两个星期的所有空闲时...

《Oracle Java SE编程自学与面试指南》最佳学习路线图2020年最新版(进大厂必备)

正确选择比瞎努力更重要!

字节跳动面试官竟然问了我JDBC?

轻松等回家通知

面试官:你连SSO都不懂,就别来面试了

大厂竟然要考我SSO,卧槽。

实时更新:计算机编程语言排行榜—TIOBE世界编程语言排行榜(2020年6月份最新版)

内容导航: 1、TIOBE排行榜 2、总榜(2020年6月份) 3、本月前三名 3.1、C 3.2、Java 3.3、Python 4、学习路线图 5、参考地址 1、TIOBE排行榜 TIOBE排行榜是根据全世界互联网上有经验的程序员、课程和第三方厂商的数量,并使用搜索引擎(如Google、Bing、Yahoo!)以及Wikipedia、Amazon、YouTube统计出排名数据。

立即提问
相关内容推荐