【问题标题】:can't create threads suspended using windows.h无法创建使用 windows.h 挂起的线程
【发布时间】:2014-08-21 17:48:02
【问题描述】:

我搜索了答案,但找不到。我正在处理线程。我有一个线程类和它的 3 个子类。当我调用这三个子类之一时,我必须在线程类中创建一个线程并使用它们的主线程(因为线程主线程是纯虚拟抽象),但问题是在它调用创建线程函数(线程的 c'tor)之前那些子干线。

线程.h

#ifndef _THREAD_H_
#define _THREAD_H_

#include <string>
#include <Windows.h>
#include <iosfwd>
#include "Mutex.h"
#include "SynchronizedArray.h"
#include "SynchronizedCounter.h"



std::string message = "";


class Thread{ 

private:
    HANDLE hThread;
    int idThread;

protected:

    SynchronizedArray *arr;
    int size;
    SynchronizedCounter *counter;

public:

    Thread(DWORD funct){   //creates a thread by calling subclasses main functions appropriately 
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) funct, NULL, 0, (LPDWORD)&idThread);
    }

    virtual DWORD WINAPI main(void*) = 0;  // pure virtual abstract class 

    void suspend(){  //suspent the thread 
        SuspendThread(hThread);
    }
    void resume(){// retume the thread 
        ResumeThread(hThread);
    }

    void terminate(){ // terminates the thread
    TerminateThread(hThread,0);
    }
    void join(){ // joins the thread 
        Mutex mut;
        mut.lock();
    }
    static void sleep(int sec){ //wrapper of sleep   by sec
        Sleep(sec*1000);
    }

};


#endif

1 of 3 个继承的 Thread 类作为示例(它们都做同样的事情)

PrintThread.h

#ifndef _PRINTINGTHREAD_H_
#define _PRINTINGTHREAD_H_
#include "SynchronizedArray.h"
#include "SynchronizedCounter.h"
#include "Thread.h"
#include <iostream>
#include "SortingThread.h"
#include "CountingThread.h"
#include <string>
#include <Windows.h>

extern CountingThread counterThread1;
extern CountingThread counterThread2;
extern SortingThread sortingThread1;
extern SortingThread sortingThread2;


class PrintingThread:public Thread{
private:
    char temp;
public:
    PrintingThread() :Thread(main(&temp)){
    }


    DWORD WINAPI main(void* param)
    {
        std::cout << "Please enter an operation ('showcounter1','showcounter2','showarray1','showarray2' or 'quit')" << std::endl;
        std::cin >> message;
        while (message != "quit")
        {
            if (message == "showcounter1")
            {
                std::cout << counterThread1<<std::endl;
            }
            else if (message == "showcounter2")
            {
                std::cout << counterThread2 << std::endl;
            }
            else if (message == "showarray1")
            {
                std::cout << sortingThread1 << std::endl;
            }
            else if (message == "showarray2")
            {
                std::cout << sortingThread2 << std::endl;
            }
            else {
                std::cout << "Invalid operation";
            }
            std::cout << "Please enter an operation ('show counter 1','show counter 2','show array 1','show array 2' or 'quit')" << std::endl;
            std::cin >> message;

        }
        return 0;

    }
};




#endif

为什么它在调用线程的 c'tor 之前调用 mains。

【问题讨论】:

  • 为什么要调用main?除了程序入口点之外,您甚至不应该拥有称为“main”的函数。将其命名为“运行”甚至“开始”。
  • 这是我被分配的。但即使我更改主名称(例如“func”),它也会做同样的事情
  • 你必须这样做:pastebin.com/CfYTY0qu 在这里查看更多信息:stackoverflow.com/questions/1372967/… 顺便说一句.. 如果你的老师给你一个作业并且有一个名为“main”的函数并且它不是入口点,你应该向他们指出。
  • (1) 你传递给CreateThread 的函数应该是static (所以你不会尝试访问任何成员)(2) 你没有向我们展示任何生成实例的代码这些类。

标签: c++ multithreading winapi inheritance


【解决方案1】:

您的PrintingThread 构造函数初始化列表实际上是调用 PrintingThread::main 并将其结果传递给Thread 构造函数。这意味着CreateThread 调用正在接收DWORD(在本例中为0)作为其函数参数。

您需要更改类设计以实际传递函数指针和上下文参数,例如:

Thread(DWORD funct){
    hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) funct, NULL, 0, (LPDWORD)&idThread);

应该是:

Thread(LPTHREAD_START_ROUTINE funct, LPVOID arg) {
    hThread = CreateThread(NULL, 0, funct, arg, 0, (LPDWORD)&idThread);

(您必须投射 funct 的事实应该是一个巨大的危险信号。)

同样,子类的构造函数将从:

PrintingThread() :Thread(main(&temp)){

到:

PrintingThread(): Thread(main, &temp) {

请注意,您的代码仍然存在其他问题,例如线程函数应该是静态的(因此您不能尝试访问成员函数)。

【讨论】:

    【解决方案2】:

    你需要做更多这样的事情:

    线程.h:

    #ifndef _THREAD_H_
    #define _THREAD_H_
    
    #include <string>
    #include <Windows.h>
    #include <iosfwd>
    #include "Mutex.h"
    #include "SynchronizedArray.h"
    #include "SynchronizedCounter.h"
    
    class Thread
    { 
    private:
        HANDLE hThread;
        DWORD idThread;
        void *pParam;    
    
        static DWORD WINAPI ThreadProc(LPVOID lpParameter)
        {
            Thread *pThis = (Thread*) lpParameter;
            return pThis->main(pThis->pParam);
        }
    
    protected:
        SynchronizedArray *arr;
        int size;
        SynchronizedCounter *counter;
    
    public:    
        Thread(void *aParam)
        {
            //creates a thread by calling subclasses main functions appropriately 
            pParam = aParam;
            hThread = CreateThread(NULL, 0, &ThreadProc, this, 0, &idThread);
        }
    
        virtual DWORD main(void*) = 0;  // pure virtual abstract class 
    
        void suspend()
        {
            //suspent the thread 
            SuspendThread(hThread);
        }
    
        void resume()
        {
            // resume the thread 
            ResumeThread(hThread);
        }
    
        void terminate()
        {
            // terminates the thread
            TerminateThread(hThread, 0);
        }
    
        void join()
        {
            // joins the thread 
            Mutex mut;
            mut.lock();
        }
    
        static void sleep(int sec)
        {
            //wrapper of sleep   by sec
            Sleep(sec*1000);
        }
    };
    
    #endif
    

    PrintThread.h:

    include <iostream>
    #include "SortingThread.h"
    #include "CountingThread.h"
    #include <string>
    #include <Windows.h>
    
    extern CountingThread counterThread1;
    extern CountingThread counterThread2;
    extern SortingThread sortingThread1;
    extern SortingThread sortingThread2;
    
    class PrintingThread : public Thread
    {
    private:
        char temp;
    
    public:
        PrintingThread() : Thread(&temp)
        {
        }
    
        virtual DWORD main(void* param)
        {
            std::string message;
    
            do
            {
                std::cout << "Please enter an operation ('showcounter1','showcounter2','showarray1','showarray2' or 'quit')" << std::endl;
                std::cin >> message;
                if (message == "quit")
                {
                    break;
                }
                if (message == "showcounter1")
                {
                    std::cout << counterThread1 << std::endl;
                }
                else if (message == "showcounter2")
                {
                    std::cout << counterThread2 << std::endl;
                }
                else if (message == "showarray1")
                {
                    std::cout << sortingThread1 << std::endl;
                }
                else if (message == "showarray2")
                {
                    std::cout << sortingThread2 << std::endl;
                }
                else
                {
                    std::cout << "Invalid operation";
                }
            }
            while (true);
    
            return 0;    
        }
    };
    
    #endif
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 2013-09-17
      • 2016-02-02
      • 1970-01-01
      • 2023-02-02
      相关资源
      最近更新 更多