Ví dụ về lập trình đa luồng trong C++/bada
2 posters
Trang 1 trong tổng số 1 trang
Ví dụ về lập trình đa luồng trong C++/bada
Thủy tìm được 1 ví dụ khá hay về lập trình đa luồng C++ ứng dụng để lập trình cho HDH bada.
Đôi khi ứng dụng của chúng ta cần xử lý một tác vụ dài, trong thời gian ứng dụng xử lý tác vụ đó thì dường như ứng dụng của ta không có bất kỳ phản ứng gì đối với các thao tác của người dùng. Đó là do ứng dụng đã dành hết tài nguyên cho việc xử lý tác vụ. Tuy nhiên, đó là trường hợp ứng dụng không sử dụng đa luồng. Trong ứng dụng đa luồng thì câu chuyện khác hẳn, ứng dụng của chúng ta vừa có thể sử lý nhiều tác vụ một lúc chẳng hạn, vừa lưu tập tin, vừa kiểm tra chính tả, vừa download cập nhật. Vậy ứng dụng đa luồng là gì và điểm khác của nó với ứng dụng chỉ có một luồng là gì?
Thông thường trong ứng dụng chỉ có 1 luồng chính thì tại 1 thời điểm, ứng dụng của bạn chỉ tập trung xử lý một tác vụ và điều này dẫn đến việc khi xử lý tác vụ dài thì ứng dụng do đang xử lý tác vụ nên không thể nhận bất cứ tương tác khác của người dùng, đây là một trải nghiệm xấu cho người dùng đồng thời làm phung phí tài nguyên hệ thống.
Đối với ứng dụng có nhiều luồng thì bộ xử lý có thể xử lý đa tác vụ trong một lúc chẳng hạn vừa kiểm tra chính tả cho bạn, download một file, lưu thay đổi trong ứng dụng… tất cả cùng một lúc. Mặc dù thực chất thì ứng dụng vẫn chỉ xử lý một luồng trong mỗi đơn vị thời gian tuy nhiên khi có đa luồng thì nó lại phân chia mỗi luồng mỗi đơn vị thời gian nhỏ để xử lý để ta có cảm tưởng rằng các luồng đang chạy đồng thời với nhau.
Source: http://www.mediafire.com/download.php?lnzazd66drkbycb
Document:http://www.mediafire.com/download.php?j2dqt1hirnlz3h9
Sau đây sẽ làm một ví dụ về sử dụng luồng.Trong ví dụ này tôi sẽ xây dựng một bộ đếm, thông báo cho listener ở luồng chính về số lần đến hiện tại. Tôi có thể mô tả luồng đó như sau:” Thông báo cho tôi về số lần đếm sau mỗi x giây và dừng việc đếm sau khi đã đếm được đến z lần.” và sử dụng một listener để nhận lấy thông điệp đó.
Lưu ý là ứng dụng này sẽ có 2 luồng gồm một luồng do chúng ta tự tạo ra thông qua lớp SecondsCounter và một luồng chính để chạy chương trình.
Trong bada có 2 cách để tạo một luồng:
- Truyền một đối tượng IRunnable vào thread và thực thi hàm Run()
- Viết một class và cho kế thừa từ lớp Thread và thực thi hàm Run()
Đồng thời có 2 loại luồng:
- Worker thread: chạy một lần và dừng lại sau khi tác vụ hoàn tất
- Event driven thread: chạy và không dừng lại sau khi tác vụ hoàn tất. Tiếp tục để đợi cho sự kiên hoặc một thông báo thoát.
Và cả 2 loại luồng như trên đều đều thực thi hàm Run(), tuy nhiên:
- Worker thread tự động hủy sau khi hàm Run() chạy xong.
- Trong khi đó Event driven thread vẫn tiếp tục tồn tại để đợi sự kiện. Bạn phải tự hủy Event driven thread.
Trong ví dụ dưới đây tôi sẽ sử dụng luồng bằng cách kế thừa lớp Thread và loại luồng được sử dụng là Worker thread.
Việc đầu tiên chúng ta cần làm là viết một lớp listener:
Mã:
#ifndef SECONDSCOUNTERLISTENER_H_
#define SECONDSCOUNTERLISTENER_H_
#include <FBase.h>
class SecondsCounterListener{
public:
virtual void OnCount(int times)=0;
};
#endif /* SECONDSCOUNTERLISTENER_H_ */
Nó đơn giản chỉ là một interface để khai báo cho sự kiện của chúng ta. Sau đây chúng ta sẽ sử dụng vào việc một lớp kế thừa từ Thread.
Mã:
#ifndef SECONDSCOUNTER_H_
#define SECONDSCOUNTER_H_
#include <FBase.h>
#include "SecondsCounterListener.h"
class SecondsCounter:
public Osp::Base::Runtime::Thread
{
public:
SecondsCounter();
virtual ~SecondsCounter();
void Init(int seconds,int timeout);
void AddSecondsCounterListener(SecondsCounterListener &listener);
virtual Osp::Base::Object * Run(void);
virtual bool OnStart(void);
virtual void OnStop(void);
protected:
int seconds_;
int timeout_;
int times_;
SecondsCounterListener * listener_;
};
#endif /* SECONDSCOUNTER_H_ */
Trong lớp của chúng ta vừa viết, do lớp được kế thừa từ lớp Thead nên việc thực thi hàm Run() là bắt buộc. Đối với 2 hàm là OnStart và OnStop thì không bắt buộc, ta có thể sử dụng 2 hàm này vào việc thực hiện các câu lệnh khởi động/xóa tài nguyên cho chương trình.
Sau đây chúng ta sẽ các hàm để thực thi lớp SecondsTimer:
Mã:
#include "SecondsCounter.h"
using namespace Osp::Base;
using namespace Osp::Base::Runtime;
SecondsCounter::SecondsCounter(void){}
SecondsCounter::~SecondsCounter(){}
void
SecondsCounter::Init(int seconds,int timeout){
this->Construct(THREAD_TYPE_WORKER);
seconds_=seconds;
timeout_=timeout;
}
bool
SecondsCounter::OnStart(){
times_=0;
}
void
SecondsCounter::OnStop(){
listener_=NULL;
}
void
SecondsCounter::AddSecondsCounterListener(SecondsCounterListener &listener){
listener_=&listener;
}
Osp::Base::Object *
SecondsCounter::Run(){
if(listener_) listener_->OnCount(times_);
do{
times_++;
Thread::Sleep(seconds_*1000);
if(listener_) listener_->OnCount(times_);
}while(times_<timeout_);
}
Sau đây tôi tạo một luồng đếm ứng dụng lớp SecondsCount mà chúng ta vừa tạo vào form chính khi sự kiện nhấn nút OK xảy ra:
Mã:
void
MainForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId)
{
switch(actionId)
{
case ID_BUTTON_OK:
{
//AppLog("OK Button is clicked! \n");
delete counter_;
counter_=new SecondsCounter;
counter_->Init(3,60);
counter_->AddSecondsCounterListener(*this);
counter_->Start();
}
break;
default:
break;
}
}
Diễn giải: khi sự kiện nhấn OK xảy ra, một thread đếm sẽ được tạo và thread này sẽ gọi hàm OnCount sau mỗi 3 giây và kết thúc khi đã đếm được đến 60.
Đồng thời, MainForm thực thi hàm OnCount để nhận sự kiện đếm mỗi khi nó xảy ra.
Mã:
void
MainForm::OnCount(int times){
String str="Count: ";
str.Append(times);
__pLabel->SetText(str);
RequestRedraw(true);
}
Vậy là chương trình đã sẵn sàng để chạy. Khi bạn nút OK bạn sẽ thấy chương trình tự đếm đến 60 và thread sau đó sẽ tự hủy.
Các có thể tải source code để xem toàn bộ câu lệnh cần thiết cho chương trình.
Chúc bạn thành công
Đôi khi ứng dụng của chúng ta cần xử lý một tác vụ dài, trong thời gian ứng dụng xử lý tác vụ đó thì dường như ứng dụng của ta không có bất kỳ phản ứng gì đối với các thao tác của người dùng. Đó là do ứng dụng đã dành hết tài nguyên cho việc xử lý tác vụ. Tuy nhiên, đó là trường hợp ứng dụng không sử dụng đa luồng. Trong ứng dụng đa luồng thì câu chuyện khác hẳn, ứng dụng của chúng ta vừa có thể sử lý nhiều tác vụ một lúc chẳng hạn, vừa lưu tập tin, vừa kiểm tra chính tả, vừa download cập nhật. Vậy ứng dụng đa luồng là gì và điểm khác của nó với ứng dụng chỉ có một luồng là gì?
Thông thường trong ứng dụng chỉ có 1 luồng chính thì tại 1 thời điểm, ứng dụng của bạn chỉ tập trung xử lý một tác vụ và điều này dẫn đến việc khi xử lý tác vụ dài thì ứng dụng do đang xử lý tác vụ nên không thể nhận bất cứ tương tác khác của người dùng, đây là một trải nghiệm xấu cho người dùng đồng thời làm phung phí tài nguyên hệ thống.
Đối với ứng dụng có nhiều luồng thì bộ xử lý có thể xử lý đa tác vụ trong một lúc chẳng hạn vừa kiểm tra chính tả cho bạn, download một file, lưu thay đổi trong ứng dụng… tất cả cùng một lúc. Mặc dù thực chất thì ứng dụng vẫn chỉ xử lý một luồng trong mỗi đơn vị thời gian tuy nhiên khi có đa luồng thì nó lại phân chia mỗi luồng mỗi đơn vị thời gian nhỏ để xử lý để ta có cảm tưởng rằng các luồng đang chạy đồng thời với nhau.
Source: http://www.mediafire.com/download.php?lnzazd66drkbycb
Document:http://www.mediafire.com/download.php?j2dqt1hirnlz3h9
Sau đây sẽ làm một ví dụ về sử dụng luồng.Trong ví dụ này tôi sẽ xây dựng một bộ đếm, thông báo cho listener ở luồng chính về số lần đến hiện tại. Tôi có thể mô tả luồng đó như sau:” Thông báo cho tôi về số lần đếm sau mỗi x giây và dừng việc đếm sau khi đã đếm được đến z lần.” và sử dụng một listener để nhận lấy thông điệp đó.
Lưu ý là ứng dụng này sẽ có 2 luồng gồm một luồng do chúng ta tự tạo ra thông qua lớp SecondsCounter và một luồng chính để chạy chương trình.
Trong bada có 2 cách để tạo một luồng:
- Truyền một đối tượng IRunnable vào thread và thực thi hàm Run()
- Viết một class và cho kế thừa từ lớp Thread và thực thi hàm Run()
Đồng thời có 2 loại luồng:
- Worker thread: chạy một lần và dừng lại sau khi tác vụ hoàn tất
- Event driven thread: chạy và không dừng lại sau khi tác vụ hoàn tất. Tiếp tục để đợi cho sự kiên hoặc một thông báo thoát.
Và cả 2 loại luồng như trên đều đều thực thi hàm Run(), tuy nhiên:
- Worker thread tự động hủy sau khi hàm Run() chạy xong.
- Trong khi đó Event driven thread vẫn tiếp tục tồn tại để đợi sự kiện. Bạn phải tự hủy Event driven thread.
Trong ví dụ dưới đây tôi sẽ sử dụng luồng bằng cách kế thừa lớp Thread và loại luồng được sử dụng là Worker thread.
Việc đầu tiên chúng ta cần làm là viết một lớp listener:
Mã:
#ifndef SECONDSCOUNTERLISTENER_H_
#define SECONDSCOUNTERLISTENER_H_
#include <FBase.h>
class SecondsCounterListener{
public:
virtual void OnCount(int times)=0;
};
#endif /* SECONDSCOUNTERLISTENER_H_ */
Nó đơn giản chỉ là một interface để khai báo cho sự kiện của chúng ta. Sau đây chúng ta sẽ sử dụng vào việc một lớp kế thừa từ Thread.
Mã:
#ifndef SECONDSCOUNTER_H_
#define SECONDSCOUNTER_H_
#include <FBase.h>
#include "SecondsCounterListener.h"
class SecondsCounter:
public Osp::Base::Runtime::Thread
{
public:
SecondsCounter();
virtual ~SecondsCounter();
void Init(int seconds,int timeout);
void AddSecondsCounterListener(SecondsCounterListener &listener);
virtual Osp::Base::Object * Run(void);
virtual bool OnStart(void);
virtual void OnStop(void);
protected:
int seconds_;
int timeout_;
int times_;
SecondsCounterListener * listener_;
};
#endif /* SECONDSCOUNTER_H_ */
Trong lớp của chúng ta vừa viết, do lớp được kế thừa từ lớp Thead nên việc thực thi hàm Run() là bắt buộc. Đối với 2 hàm là OnStart và OnStop thì không bắt buộc, ta có thể sử dụng 2 hàm này vào việc thực hiện các câu lệnh khởi động/xóa tài nguyên cho chương trình.
Sau đây chúng ta sẽ các hàm để thực thi lớp SecondsTimer:
Mã:
#include "SecondsCounter.h"
using namespace Osp::Base;
using namespace Osp::Base::Runtime;
SecondsCounter::SecondsCounter(void){}
SecondsCounter::~SecondsCounter(){}
void
SecondsCounter::Init(int seconds,int timeout){
this->Construct(THREAD_TYPE_WORKER);
seconds_=seconds;
timeout_=timeout;
}
bool
SecondsCounter::OnStart(){
times_=0;
}
void
SecondsCounter::OnStop(){
listener_=NULL;
}
void
SecondsCounter::AddSecondsCounterListener(SecondsCounterListener &listener){
listener_=&listener;
}
Osp::Base::Object *
SecondsCounter::Run(){
if(listener_) listener_->OnCount(times_);
do{
times_++;
Thread::Sleep(seconds_*1000);
if(listener_) listener_->OnCount(times_);
}while(times_<timeout_);
}
Sau đây tôi tạo một luồng đếm ứng dụng lớp SecondsCount mà chúng ta vừa tạo vào form chính khi sự kiện nhấn nút OK xảy ra:
Mã:
void
MainForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId)
{
switch(actionId)
{
case ID_BUTTON_OK:
{
//AppLog("OK Button is clicked! \n");
delete counter_;
counter_=new SecondsCounter;
counter_->Init(3,60);
counter_->AddSecondsCounterListener(*this);
counter_->Start();
}
break;
default:
break;
}
}
Diễn giải: khi sự kiện nhấn OK xảy ra, một thread đếm sẽ được tạo và thread này sẽ gọi hàm OnCount sau mỗi 3 giây và kết thúc khi đã đếm được đến 60.
Đồng thời, MainForm thực thi hàm OnCount để nhận sự kiện đếm mỗi khi nó xảy ra.
Mã:
void
MainForm::OnCount(int times){
String str="Count: ";
str.Append(times);
__pLabel->SetText(str);
RequestRedraw(true);
}
Vậy là chương trình đã sẵn sàng để chạy. Khi bạn nút OK bạn sẽ thấy chương trình tự đếm đến 60 và thread sau đó sẽ tự hủy.
Các có thể tải source code để xem toàn bộ câu lệnh cần thiết cho chương trình.
Chúc bạn thành công
error- Tổng số bài gửi : 17
Join date : 15/11/2010
Re: Ví dụ về lập trình đa luồng trong C++/bada
Code thi day du roi, ban nen giai thich cac doan code ro hon them 1 chut nua la ok. Thanks ban.
tinlv_i91c- Tổng số bài gửi : 39
Join date : 09/04/2010
Đến từ : Quang Ngai
Re: Ví dụ về lập trình đa luồng trong C++/bada
tinlv_i91c đã viết:Code thi day du roi, ban nen giai thich cac doan code ro hon them 1 chut nua la ok. Thanks ban.
Mình đã cố gắng giải thích quá trình hoạt động trước khi trình bày code rồi. Nếu có chỗ nào ko hiểu bạn chỉ rõ ra mình sẽ chú thích riêng phần đó cho bạn! Vì nhiều đoạn code cũng khá đơn giản nên mình ko chú thích vào sợ làm rối source!
Rất cám ơn sự quan tâm của bạn dành cho bài viết!
error- Tổng số bài gửi : 17
Join date : 15/11/2010
Similar topics
» Thảo luận Bài 5
» Lập trình đa luồng trong java
» Thảo luận Bài 5
» Lập trình đa luồng trong WinDows
» Thảo luận Bài 5
» Lập trình đa luồng trong java
» Thảo luận Bài 5
» Lập trình đa luồng trong WinDows
» Thảo luận Bài 5
Trang 1 trong tổng số 1 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết