簡體   English   中英

QNX c ++線程問題

[英]QNX c++ thread question

我有一個關於此代碼的問題,我想在QNX上運行:

class ConcreteThread : public Thread
{
public:
    ConcreteThread(int test)
    {
        testNumber = test;
    }

    void *start_routine() 
    { 
        for(int i = 0; i < 10; i++)
        {
            sleep(1);
            cout << testNumber << endl;
        }   
    }

private:
    int testNumber;
};




class Thread 
{
public:
    Thread(){};

    int Create()
    {
        pthread_t m_id;
        return pthread_create(&m_id, NULL, &(this->start_routine_trampoline), this);
    }

protected:
    virtual void *start_routine() = 0;

private:

    static void *start_routine_trampoline(void *p)
    {
        Thread *pThis = (Thread *)p;
        return pThis->start_routine();
    }
};

現在,當我在* start_routine中沒有睡眠的情況下運行此代碼時,它將簡單地打印數字10次,然后繼續下一行代碼(順序而不是並行)。 但是,當我在代碼中使用睡眠時,它根本不打印任何數字,只是繼續下一行代碼。 為什么不睡覺工作,我怎樣才能創建這樣的線程,而不是運行順序?

注1:如果您只有1個處理器,則無論您創建多少個線程,代碼都只能按順序執行。 每個線程在換出下一個線程之前都會獲得一段處理器時間。

注意2:如果主線程退出pthreads將在它們有機會執行之前終止所有子線程。

現在回答你的問題:

沒有睡覺。 線程一旦啟動就有足夠的時間在單個切片中給出完全執行循環10次。

隨着睡眠:你的工作線程將睡一整秒。 所以你的主線程有時間做很多工作。 如果主線程在此時退出,則工作人員將被殺死。

我會做出以下更改:

//  Remove the Create() method
//  Put thread creation in the constructor.
//  Make the thread variable part of the object

pthread_t m_id;

Thread()
{
    if (pthread_create(&m_id, NULL, &(this->start_routine_trampoline), this) != 0)
    {
        throw std::runtime_error("Thread was not created");
    }
}

// Make sure the destructor waits for the thread to exit.
~Thread()
{
    pthread_join(m_id);
}

如果你去看看增強線程庫。 你會發現像這樣的所有小錯誤已經得到了照顧; 從而使線程更易於使用。

另請注意。 使用靜態可能有效,但它不可移植。 這是因為pthread是一個C庫,因此期望一個帶有C ABI的函數指針。 您只是在這里為您的平台幸運。 您需要將此定義為函數並使用extern“C”聲明ABI

// This needs to be a standard function with C Interface.
extern "C" void *start_routine_trampoline(void *p)
{
}

嘗試使pthread_t id成為類成員而不是函數局部變量。 這樣調用者可以pthread_join它。

不這樣做在技術上是資源泄漏(除非線程特別不可連接)。 加入將避免Martin York描述的問題。

來自man pthread_join:

連接的線程必須處於可連接狀態:它不能使用pthread_detach(3)或PTHREAD_CREATE_DETACHED屬性分離到pthread_create(3)。

當可連接線程終止時,其內存資源(線程描述符和堆棧)不會被釋放,直到另一個線程對其執行pthread_join。 因此,必須為創建的每個可連接線程調用pthread_join一次,以避免內存泄漏。

關於這里的切線...關於馬丁約克的帖子:

另請注意。 使用靜態可能有效,但它不可移植。 這是因為pthread是一個C庫,因此期望一個帶有C ABI的函數指針。 您只是在這里為您的平台幸運。 您需要將此定義為函數並使用extern“C”聲明ABI

我不太確定......

(1)C ++被設計為盡可能與C兼容。 有一些差異......但我的印象是extern“C”主要用於規避實現C ++函數重載所需的名稱修改。

(2)看起來,一旦你有了函數指針,調用約定(在堆棧上被推入以進行函數調用)在C&C ++之間必須是相同的。 否則,函數指針將如何工作?

例如:

C代碼:

void bar( int i ) { printf( "bar %d\n", i ); }

C ++代碼:

class Foo
{
public:
  static void foo( int i ) { cout << "foo " << i << endl; }
};

extern "C" { void bar(int); }

int main()
{
  void (*p)(int);

  p = & Foo::foo;
  (*p)(1);

  p = & bar;
  (*p)(2);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM