/**********類ConsumerThread使用全域性變數************/
#include "consumerthread.h"
#include "res.h"
#include <QDebug>

ConsumerThread::ConsumerThread(QObject* parent)
    : QThread(parent) {

}

ConsumerThread::ConsumerThread() {

}

ConsumerThread::~ConsumerThread() {

}

void ConsumerThread::run() {
     for (int i = 0; i < g_nDataSize; i++) {
          g_qsemUsedBytes.acquire();              
          qDebug()<<"Consumer "<<g_szBuffer[i % g_nBufferSize];
          g_szBuffer[i % g_nBufferSize] = ' ';
          g_qsemFreeBytes.release();
         
     }
     qDebug()<<"&&Consumer Over";
}
/**************************/

    也可以把全域性變數的宣告和定義放在一起,這樣可以防止忘記了定義,如上面的extern char g_szBuffer[g_nBufferSize]; 然後把引用它的檔案中的#include "res.h"換成extern char g_szBuffer[];。
    但是這樣做很不好,因為你無法使用#include "res.h"(使用它,若達到兩次及以上,就出現重定義錯誤;注:即使在res.h中加#pragma once,或#ifndef也會出現重複定義,因為每個編譯單元是單獨的,都會對它各自進行定義),那麼res.h宣告的其他函式或變數,你也就無法使用了,除非也都用extern修飾,這樣太麻煩,所以還是推薦使用.h中宣告,.cpp中定義的做法。

(5)靜態全域性變數(static)
    注意使用static修飾變數,就不能使用extern來修飾,即static和extern不可同時出現。
    static修飾的全域性變數的宣告與定義同時進行,即當你在標頭檔案中使用static聲明瞭全域性變數,同時它也被定義了。
    static修飾的全域性變數的作用域只能是本身的編譯單元。在其他編譯單元使用它時,只是簡單的把其值複製給了其他編譯單元,其他編譯單元會另外開個記憶體儲存它,在其他編譯單元對它的修改並不影響本身在定義時的值。即在其他編譯單元A使用它時,它所在的實體地址,和其他編譯單元B使用它時,它所在的實體地址不一樣,A和B對它所做的修改都不能傳遞給對方。
    多個地方引用靜態全域性變數所在的標頭檔案,不會出現重定義錯誤,因為在每個編譯單元都對它開闢了額外的空間進行儲存。