linux C++ 面向物件執行緒類封裝
1.封裝遇到的問題
將pthread執行緒封裝為抽象類,這樣使用者在使用執行緒時,只需要繼承一下這個抽象類,並實現相應的介面就可以了。這樣做的好處是使用者可以將注意力集中線上程所要執行的邏輯上,而不需要關注建立執行緒、銷燬執行緒等細節問題上。
我們抽象類的名稱為Thread,其中有一個成員函式run,該函式為的宣告形式為:
void run() = 0;
即將該成員函式宣告為純虛擬函式,使用者繼承此類必須要實現此成員函式。Thread中還有另外一個成員函式start,該函式的宣告形式為:
void start();
使用者在子類中呼叫start方法,將啟動執行緒,並在執行緒中執行run函式。
最常想到的方法就是在start方法中使用pthread_create建立一個執行緒,並呼叫run函式。如下面這樣的實現:
void start()
{
int status;
status = pthread_create(_pThread,NULL,Thread::run,NULL);
if(status != 0)
err_abort(“creating thread failure”,status);
}
這樣編譯肯定是不能通過的,這是因為pthread_create要求的執行緒例程的介面形式為:
void *(*thread_routin)(void *args);
而上面程式碼中提供的執行緒例程的介面形式為:
void Thread::run()
顯然不符合要求的介面。
為了能夠在start中呼叫run函式,我們不得不採用一種迂迴的方式。下面提供兩種方法:一種是使用靜態成員函式,另外一種是使用友元函式。
靜態成員函式的作用域是全域性的,而不僅僅侷限於某個函式中。靜態成員函式的實現方法和C語言中的普通函式類似,因此靜態函式沒有this指標,靜態函式只能操作靜態成員變數。之所以將靜態函式封裝到類中,在很大程度上也只是為了滿足面向物件的特性之一-----封裝性。
2.使用靜態函式
需要特別注意的是mian函式中使用pthread_create
#ifndef THREAD_H
#define THREAD_H
#include <iostream>
#include <pthread.h>
using namespace std;
class Thread
{
private:
//當前執行緒的執行緒ID
pthread_t tid;
//執行緒的狀態
int threadStatus;
//獲取執行方法的指標
static void * thread_proxy_func(void * args);
//內部執行方法
void* run1();
public:
//執行緒的狀態-新建
static const int THREAD_STATUS_NEW = 0;
//執行緒的狀態-正在執行
static const int THREAD_STATUS_RUNNING = 1;
//執行緒的狀態-執行結束
static const int THREAD_STATUS_EXIT = -1;
//建構函式
Thread();
//執行緒的執行實體
virtual void run()=0;
//開始執行執行緒
bool start();
//獲取執行緒ID
pthread_t getThreadID();
//獲取執行緒狀態
int getState();
//等待執行緒直至退出
void join();
//等待執行緒退出或者超時
void join(unsigned long millisTime);
};
class MultiThread : public Thread
{
public:
void run()
{
int number = 0;
for (int i = 0; i < 10; i++)
{
cout << "Current number is " << number++;
cout << " PID is " << getpid() << " TID is " << getThreadID() << endl;
sleep(1);
}
}
};
#endif
Thread.cpp
#include "thread.h"
void* Thread::run1()
{
threadStatus = THREAD_STATUS_RUNNING;
tid = pthread_self();
run();
threadStatus = THREAD_STATUS_EXIT;
tid = 0;
pthread_exit(NULL);
}
Thread::Thread()
{
tid = 0;
threadStatus = THREAD_STATUS_NEW;
}
bool Thread::start()
{
int iRet = 0;
pthread_create(&tid, NULL, thread_proxy_func, this) == 0;
}
pthread_t Thread::getThreadID()
{
return tid;
}
int Thread::getState()
{
return threadStatus;
}
void Thread::join()
{
if (tid > 0)
{
pthread_join(tid, NULL);
}
}
void * Thread::thread_proxy_func(void * args)
{
Thread * pThread = static_cast<Thread *>(args);
pThread->run();
return NULL;
}
void Thread::join(unsigned long millisTime)
{
if (tid == 0)
{
return;
}
if (millisTime == 0)
{
join();
}else
{
unsigned long k = 0;
while (threadStatus != THREAD_STATUS_EXIT && k <= millisTime)
{
usleep(100);
k++;
}
}
}
main.cpp
#include <iostream>
#include <pthread.h>
#include "thread.h"
using namespace std;
int main(int argv,char *argc)
{
MultiThread tt;
tt.start();
tt.join();
return 0;
}
3.使用友元函式
友元函式的作用和靜態函式相同,都起到一個代理的作用。需要將物件的指標作為引數傳遞給這個友元函式,然後在友元函式中呼叫run函式。程式碼如下,
由三個檔案構成:Thread.h(類的宣告檔案),Thread.cpp(類的實現檔案),main.cpp(測試檔案):
Thread.h#ifndef THREAD_H
#define THREAD_H
#include <iostream>
#include <pthread.h>
using namespace std;
class Thread
{
private:
//當前執行緒的執行緒ID
pthread_t tid;
//執行緒的狀態
int threadStatus;
//獲取執行方法的指標
//static void * thread_proxy_func(void * args);
friend void * thread_proxy_func(void * args);
//內部執行方法
void* run1();
public:
//執行緒的狀態-新建
static const int THREAD_STATUS_NEW = 0;
//執行緒的狀態-正在執行
static const int THREAD_STATUS_RUNNING = 1;
//執行緒的狀態-執行結束
static const int THREAD_STATUS_EXIT = -1;
//建構函式
Thread();
//執行緒的執行實體
virtual void run()=0;
//開始執行執行緒
bool start();
//獲取執行緒ID
pthread_t getThreadID();
//獲取執行緒狀態
int getState();
//等待執行緒直至退出
void join();
//等待執行緒退出或者超時
void join(unsigned long millisTime);
};
class MultiThread : public Thread
{
public:
void run()
{
int number = 0;
for (int i = 0; i < 10; i++)
{
cout << "Current number is " << number++;
cout << " PID is " << getpid() << " TID is " << getThreadID() << endl;
sleep(1);
}
}
};
#endif
Thread.cpp
#include "thread.h"
void* Thread::run1()
{
threadStatus = THREAD_STATUS_RUNNING;
tid = pthread_self();
run();
threadStatus = THREAD_STATUS_EXIT;
tid = 0;
pthread_exit(NULL);
}
Thread::Thread()
{
tid = 0;
threadStatus = THREAD_STATUS_NEW;
}
bool Thread::start()
{
int iRet = 0;
pthread_create(&tid, NULL, thread_proxy_func, this) == 0;
}
pthread_t Thread::getThreadID()
{
return tid;
}
int Thread::getState()
{
return threadStatus;
}
void Thread::join()
{
if (tid > 0)
{
pthread_join(tid, NULL);
}
}
void * thread_proxy_func(void * args)
{
Thread * pThread = static_cast<Thread *>(args);
pThread->run();
return NULL;
}
void Thread::join(unsigned long millisTime)
{
if (tid == 0)
{
return;
}
if (millisTime == 0)
{
join();
}else
{
unsigned long k = 0;
while (threadStatus != THREAD_STATUS_EXIT && k <= millisTime)
{
usleep(100);
k++;
}
}
}
main.cpp
#include <iostream>
#include "thread.h"
using namespace std;
int main(int argv,char *argc)
{
MultiThread tt;
tt.start();
tt.join();
return 0;
}
執行結果
makefile參考
ANAME=server
CC=g++
TMP_PROGS = main.cpp thread.cpp
PROGS = $(TMP_PROGS)
OBJS = $(PROGS:.cpp=.o)
INCDIR=./
all: $(ANAME)
$(ANAME): $(OBJS)
@echo "--------------- .o to ELT "
$(CC) -g $(TMP_PROGS) -o [email protected] -lpthread
.cpp.o:
@echo "--------------- CPP to .o "
$(CC) -g $(CFLAGS) -I$(INCDIR) -c $< -o [email protected] -lpthread
clean:
$(RM) $(ANAME)
$(RM) *.o
相關推薦
linux C++ 面向物件執行緒類封裝
1.封裝遇到的問題 將pthread執行緒封裝為抽象類,這樣使用者在使用執行緒時,只需要繼承一下這個抽象類,並實現相應的介面就可以了。這樣做的好處是使用者可以將注意力集中線上程所要執行的邏輯上,而不需要關注建立執行緒、銷燬執行緒等細節問題上。 我們抽象類的名稱為Th
C++11的執行緒類,建立的執行緒,如何設定優先順序?
SetThreadPriorityThe SetThreadPriority function sets the priority value for the specified thread. This value, together with the priority
Linux C++的多執行緒程式設計
1. 引言 執行緒(thread)技術早在60年代就被提出,但真正應用多執行緒到作業系統中去,是在80年代中期,solaris是這方面的佼佼者。傳統的Unix也支援執行緒的概念,但是在一個程序(process)中只允許有一個執行緒,這樣多執行緒就意味著多程序。現在,多執
Linux C++的多執行緒程式設計(新手最全教程)
1. 引言 執行緒(thread)技術早在60年代就被提出,但真正應用多執行緒到作業系統中去,是在80年代中期,solaris是這方面的佼佼者。傳統的Unix也支援執行緒的概念,但是在一個程序(process)中只允許有一個執行緒,這樣多執行緒就意味著多程序。現在,多執行緒技術已經被許多作業系統所支援
windows程式設計 使用C++實現多執行緒類
本文簡單介紹如何在windows程式設計中實現多執行緒類,供大家學習參考,也希望大家指正。 有時候我們想在一個類中實現多執行緒,主執行緒在某些時刻獲得資料,可以“通知”子執行緒去處理,然後把結果返回。下面的例項是主執行緒每隔2s產生10個隨機數,將這10隨機數傳給多執行緒
Linux C語言多執行緒庫Pthread中條件變數的的正確用法逐步詳解
(本文的讀者定位是瞭解Pthread常用多執行緒API和Pthread互斥鎖,但是對條件變數完全不知道或者不完全瞭解的人群。如果您對這些都沒什麼概念,可能需要先了解一些基礎知識) Pthread庫的條件變數機制的主要API有三個: int pthread_cond_w
c++類和類的封裝,物件執行緒封裝
1. C++面向物件程式設計介紹 面向物件程式設計(Object Oriented Programming),簡稱OOP。 在傳統的面向過程程式設計中,資料以及資料的相關操作函式都是分離的獨立個體; 物件,如周圍的一切其實都是物件;就程式設計角度,物
c++11 thread 封裝成簡單執行緒類
這幾天學習qt的時候發現Qt的執行緒類和java的執行緒類差不多,因為要讀取攝像頭然後顯示到介面上,執行緒需要不停的讀。大體結構就是這樣了: void run(){ while( !當前執行緒被中斷){ //work } }
《C++面向物件多執行緒程式設計》讀後感
開始時間:2010-10-19 結束時間:2010-12-12 閱讀方式:精讀,除附錄部分關於非WIN32系統外的API部分。 圖書介質:掃描PDF 讀後感 用了將近2個月的時間讀完了《C++面向物件多
C++面向物件程式設計——概述(物件、類、抽象、封裝、繼承、多型)
前言:今天第一次上C++課程。根據老師的所講內容進度,記錄C++知識!!! 第一章 問題一:什麼是面向物件程式設計? 面向物件程式設計是一種新的程式設計範型。主要特徵是:程式=物件+訊息 面向物件程式設計的
linux下C開發多執行緒程式
轉:https://blog.csdn.net/lingfemg721/article/details/6574804 linux下用C開發多執行緒程式,Linux系統下的多執行緒遵循POSIX執行緒介面,稱為pthread。 #
補習:C# 面向物件三大特性:封裝、繼承、多型
C# 面向物件三大基本特性 封裝、繼承、多型 1、封裝 隱藏物件的屬性和實現細節,僅對外公開介面,控制在程式中屬性的讀取和修改的訪問級別。 C# 封裝根據具體的需要,設定使用者的訪問許可權,並通過 訪問修飾符 來實現。 一個 訪問修飾符 定義了一個類成員的範圍和可
C++設計模式-面向物件程式設計要點以及封裝性特點
目錄 1.面向物件程式設計要點 2.單使用封裝性的例子 1.面向物件程式設計要點 面向物件程式設計要注意什麼: 注意3點: 1.可維護性; 2.可擴充套件性; 3.可複用性; 4.靈活性好; 注意:要儘可能的避免重複; 要求業務邏輯與介面分
執行緒類基本封裝
執行緒類 面向物件風格: 通過子類重寫run方法 實現多型 從而實現依賴反轉 但我們要提供抽象類和介面 將run()方法和startThread()方法宣告的私有的 其實本沒有有必要宣告為公有的 我們在start------>startThread ----
python中的面向物件學習以及類的封裝(這篇文章初學者一定要好好看)
這篇文章對於初學者可以很有效的理解面對過程、面對物件 一、首先介紹一下面向過程和麵向物件的比較: 面向過程 VS 面向物件 程式設計正規化 程式設計是程式設計師用特定的語法+資料結構+演算法組成的程式碼來告訴計算機如何執行任務的過程 , 一個程式是程式設計師為了得到一個任務結果而
c#面向物件程式設計—— 彈出窗體以及新建窗體類的返回值,圖片匯入,退出問題
新建窗體類: 在form1的載入事件中加入以下語句: private void Form1_Load(object sender, EventArgs e) { Message mes = new Message();
Java基礎複習第七天——面向物件思想、類、物件、封裝、構造方法、JavaBean
目錄 一 面向物件思想 1.概述 2.面向物件的三大特徵 3.類和物件 4.類和物件的關係 5.類的定義 6.成員變數和區域性變數 7.物件的使用格式 8.物件記憶體圖 二.封裝
利用C++11實現執行緒task的簡單封裝
#include <functional> #include <thread> #include <type_traits> /*Compile only if 'F' is callable. F maybe function, la
C#面向物件 |多型之抽象類案例
使用抽象類結構實現 NPC 模組 在遊戲中會出現很多種不同用途的 NPC,這些 NPC有各自的存在價值和作用,同時又具備一些共性的東西。在開發 NPC 系統時,往往需要提取共性,獨立出一個父類,然後子類繼承父類,實現不同作用的 NPC。 分析 任務 NPC,商販 NPC,鐵匠 NPC,三種 NPC
c++ 網路程式設計(九)TCP/IP LINUX/windows下 多執行緒超詳細教程 以及 多執行緒實現服務端
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <process.h> #include <winsock2.h> #include <win