线程

  1. 每个线程都有自己独立的 堆栈

关键函数

CreateThread/_beginthreadex 创建线程
ExitThread/_endthreadex 退出线程
SuspendThread 挂起线程
ResumeThread 恢复线程
TerminateThread 终止线程
GetCurrentThread 获取当前线程句柄(伪)
GetCurrentThreadId 获取当前线程ID
GetExitCodeThread 获取线程退出码

单独释放句柄

  1. 线程和线程句柄(Handle)不是一个东西,线程句柄是一个内核对象。
  2. 我们可以通过句柄来操作线程,但是线程的生命周期和线程句柄的生命周期不一样的
  3. 线程的生命周期就是线程函数从开始执行到return,线程句柄的生命周期是从CreateThread返回到你CloseHandle()。
  4. 所有的内核对象(包括线程Handle)都是系统资源,如果不释放句柄,系统的句柄资源很快就用光了。
  5. 如果你CreateThread以后需要对这个线程做一些操作,比如改变优先级,被其他线程等待,强制TermateThread等,就要保存这个句柄,使用完了在CloseHandle
  6. 如果你开了一个线程,而不需要对它进行如何干预,CreateThread后直接CloseHandle就行了。
  7. CloseHandel(ThreadHandle )只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了。并没有结束线程。

win api 创建线程

函数原型

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes,
  SIZE_T                  dwStackSize,
  LPTHREAD_START_ROUTINE  lpStartAddress,
  __drv_aliasesMem LPVOID lpParameter,
  DWORD                   dwCreationFlags,
  LPDWORD                 lpThreadId
);

线程退出的方案

  1. 线程自己结束

    推荐,释放所有占用的内存
  2. ExitThread

    相当于直接return,但是不会释放内存(c++ 对象)
  3. TerminateThread

    1. 拥有线程的进程终止运行之前,系统不撤销线程堆栈
    2. DLL接不到通知
    3. 异步运行,不能保证线程什么时候被结束
    4. 通过 WaitForSingleObject(m_hThread, INFINITE) 来等待某个线程结束
  4. TerminateProcess

    通过关闭 进程直接关闭所有线程

实例

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}
//自定义线程函数
DWORD WINAPI ThreadProc(LPVOID lpParameter)   // thread data);
{
    char szBuf[256] = { 0 };
    DWORD tid = GetCurrentThreadId();

    wsprintfA(szBuf, "thread id : %d", tid);

    while (true) {

        OutputDebugStringA(szBuf);
        Sleep(1000);
    }

    return 0;
}

void MainWindow::on_create_clicked()
{
    DWORD dwThreadID = 0;
    //创建线程
    m_hThread = CreateThread(NULL,
                 0,
                 (LPTHREAD_START_ROUTINE)ThreadProc,
                 NULL,
                 CREATE_SUSPENDED,
                 &dwThreadID);
}

void MainWindow::on_pause_clicked()
{
    SuspendThread(m_hThread);

}

void MainWindow::on_ternimate_clicked()
{
    TerminateThread(m_hThread, 123);
}

void MainWindow::on_resume_clicked()
{
    ResumeThread(m_hThread);
}

void MainWindow::on_pushButton_clicked()
{
    DWORD dwExit;

    WaitForSingleObject(m_hThread, INFINITE);

    BOOL bRet =GetExitCodeThread(m_hThread, &dwExit);

    qDebug() << dwExit << endl;
}
Last modification:October 26, 2018
如果觉得我的文章对你有用,请随意赞赏