Symbian C/S 模式编程实例(线程)

漁_夫 2011-04-21 04:16:59
加精
原文链接地址如下:
http://blog.csdn.net/arthersophy/archive/2010/04/20/5506639.aspx

线程编程在symbian os中不被鼓励使用,想来原因大家都已经知道了(线程上下文切换比活动对象开销大 等),但是对于一些特殊的需求及应用,还是需要多线程编程的,比如多媒体编程。在播放流媒体或者声音的时候,必须保证任务的连续性。

具体理论不明白的地方,请参看:Symbian c/s 机制分析

自己写了个例子,代码如下。

RThreadClien.h

public RThreadClient : public RSessionBase
{
public:
IMPORT_C RThreadClient();
IMPORT_C ~RThreadClient();

public:
IMPORT_C TInt ConnectToServer(const TDesC& aName);
IMPORT_C TInt SendReceive(TInt aFunction) const;
IMPORT_C TInt SendReceive(TInt aFunction,const TIpcArgs& aArgs) const;
IMPORT_C void SendReceive(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus) const;


private:
TVersion Version();
void DoConnectL(const TDesC& aName);
};

RThreadClient.cpp

#include "ThreadClient.h"
#include "ThreadServer.h"

const TInt KNumConnectRetries = 5;
const TInt KMaxNumberOfMessageSlots = 255;

EXPORT_C RThreadClient::RThreadClient()
{
}

EXPORT_C RThreadClient::~RThreadClient()
{
}

EXPORT_C TInt RThreadClient::ConnectToServer(const TDesC& aName) //连接到server
{
TInt ret = KErrNone;
if (Handle() == 0) // 保证一个client有一个handle.
{
TRAPD(ret, DoConnectL(aName));
if (ret != KErrNone)
{
Close();
}
}
return ret;
}


TVersion RThreadClient::Version()
{
TVersion v(1,1,1);
return v;
}

static void ThreadFunL(TAny* aData)
{
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler(); //安装活动调度器
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);

CThreadServer* server = CThreadServer::NewL(); //new a custom server
CleanupStack::PushL(server);
const TDesC& name = *static_cast<const TDesC*>(aData);
server->StartL(name);
RThread::Rendezvous(KErrNone);

CActiveScheduler::Start(); //启动活动调度器

// Delete active scheduler
CleanupStack::PopAndDestroy(2, scheduler); //scheduler, engine
}

static TInt ThreadFun(TAny* aData)
{
CTrapCleanup* cleanup = CTrapCleanup::New(); //手动安装清楚栈。
TInt error = KErrNone;
if(cleanup)
{
TRAP(error, ThreadFunL(aData));

}
delete cleanup;

return error;
}

void DoLaunchThreadL(const TDesC& aThreadName, TBool aUseSemaphore)
{
TRequestStatus started, died;

RThread thread;
User::LeaveIfError(thread.Create(aThreadName, ThreadFun, 8192, NULL, const_cast<TDesC*>(&aThreadName)));//创建一个用户线程。

thread.Logon(died); // 向线程注册一下,你能够监听到线程取消或者死忘。

if (aUseSemaphore)
{
thread.Rendezvous(started); // 线程同步一种方式。不是数据交换。请求得到服务线程调用 Rendezvous(TInt) 的通知
if (started != KRequestPending)
{
thread.Kill(0); // abort startup
return;
}
}

// Logon OK - Start the epocExe
thread.Resume(); //启动线程。

if (aUseSemaphore)
{
User::WaitForRequest(started, died); // wait for start or death
if (started==KRequestPending)
{
thread.RendezvousCancel(started);
thread.Close();
User::LeaveIfError(died.Int());
}
}

thread.LogonCancel(died); //取消注册
thread.Close();
User::WaitForRequest(died);
}

void RThreadClient::DoConnectL(const TDesC& aName)
{
TInt err = KErrNone;
TInt count = 0;
TBool serverStarted = EFalse;
FOREVER
{
err = CreateSession(aName, Version(), KMaxNumberOfMessageSlots); // 创建session,session代表一个client和

// server的链接,也就是说,如果Client端调用了RSessionBase::CreateSession(),那么Server端的 NewSessionL就会被调用。猜//测下Server的实现如下:当Client端调用了RSessionBase::CreateSession (),内核找到相应的Server,然后Server线程的AS会//check这个Client在Server端有没有对应的Session,如果没有就调 用NewSessionL来创建一个Session。Client和Server后续的数据// 操作都通过这个Session来完成。 ×区别于自定义的CThreadServer ×
if (err == KErrNone) //已经存在了
{
break;
}
if ((err != KErrNotFound) || (count++ == KNumConnectRetries))
{
User::LeaveIfError(err);
}
if (!serverStarted)
{
DoLaunchThreadL(aName, ETrue);
serverStarted = ETrue;
}
}
}

EXPORT_C TInt RThreadClient::SendReceive(TInt aFunction, const TIpcArgs& aArgs) const
{
return RSessionBase::SendReceive(aFunction, aArgs);
}

EXPORT_C TInt RThreadClient::SendReceive(TInt aFunction) const
{
return RSessionBase::SendReceive(aFunction);
}

EXPORT_C void RThreadClient::SendReceive(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus) const
{
RSessionBase::SendReceive(aFunction, aArgs, aStatus);
}

CThreadServer.h


#ifndef __THREADSERVER_H__
#define __THREADSERVER_H__

#include <e32base.h>

enum TRequestType
{
EDoStart,
ECancel,
ECustomCommand,
};

// CServer2 是一个AO,从客户线程接受请求,然后把这些请求分发到相应的服务器端的客户session。它可以利用客户线程请求来创

//建服务器端的客户线程。
public CThreadServer : public CServer2
{
public:
static CThreadServer* NewL();
~CThreadServer();

void DisconectServer();

private:
// From CServer2
virtual CSession2* NewSessionL(const TVersion& aVersion,
const RMessage2 &aMessage) const;


private:
CThreadServer();
void ConstructL();
TInt SessionCount();

private:
};


#endif // __THREADSERVER_H__

CThreadServer.cpp
#include <BAUTILS.H>
#include <eikenv.h>
#include <w32std.h>
#include "ThreadServer.h"
#include "ThreadSession.h"



CThreadServer* CThreadServer::NewL()
{
CThreadServer* self = new (ELeave) CThreadServer();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}

CThreadServer::CThreadServer() : CServer2(CActive::EPriorityStandard)
{
}

CThreadServer::~CThreadServer()
{
}

void CThreadServer::ConstructL()
{
}


CSession2* CThreadServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
{
const TVersion v(1, 1, 1);
if (!User::QueryVersionSupported(v, aVersion))
{
User::Leave(KErrNotSupported);
}
return CThreadSession::NewL();
}

void CThreadServer::DisconectServer()
{
if (SessionCount() == 0)
{
CActiveScheduler::Stop();
}
}

TInt CThreadServer::SessionCount()
{
iSessionIter.SetToFirst();
TInt i = 0;
while (iSessionIter++)
{
++i;
}
return i;
}
//end of file

CThreadSessio.h

#ifndef PointrProtectSESSION_H_
#define PointrProtectSESSION_H_

#include <e32base.h>
#include <f32file.h>
// CSession2 服务器端的客户Session, 充当 Client和Server 的通信信道,一个Client线程能和一个Server并发多个线程。
class CThreadServer;
public CThreadSession : public CSession2
{
public:
static CThreadSession* NewL();
~CThreadSession();

public:
// From CSession2
virtual void ServiceL(const RMessage2& aMessage);
virtual void Disconnect(const RMessage2& aMessage);

private:
CThreadSession();
void ConstructL();

private:
void DoServiceL(const RMessage2& aMessage);


private:
};

#endif /*PointrProtectSESSION_H_*/

CThreadSession.cpp

#include "ThreadSession.h"
#include "ThreadServer.h"
#include "BaseWorker.h"


CThreadSession* CThreadSession::NewL()
{
CThreadSession* self = new (ELeave) CThreadSession();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}

CThreadSession::CThreadSession()
{
}

CThreadSession::~CThreadSession()
{
}

void CThreadSession::ConstructL()
{
}

void CThreadSession::ServiceL(const RMessage2& aMessage)
{
TRAPD(err, DoServiceL(aMessage));
if (err != KErrNone)
{
aMessage.Complete(err);
}
}


void CThreadSession::DoServiceL(const RMessage2& aMessage)
{
switch (aMessage.Function())
{
case EDoStart:
{

}
break;
case ECancel:
{

}
break;
default:
{

}
break;
}
}

void CThreadSession::Disconnect(const RMessage2& aMessage)
{
CThreadServer* server = const_cast<CThreadServer*>(static_cast<const CThreadServer* >(Server()));
CSession2::Disconnect(aMessage);
server->DisconectServer();
}
...全文
723 55 打赏 收藏 转发到动态 举报
写回复
用AI写文章
55 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2011-08-13
  • 打赏
  • 举报
回复
达人啊...学习了
molookoo 2011-07-20
  • 打赏
  • 举报
回复
收下了!
火星大能猫 2011-04-29
  • 打赏
  • 举报
回复
塞班开发的越来越少了
ztifu 2011-04-28
  • 打赏
  • 举报
回复
symbian已走到尽头
ipuhua 2011-04-27
  • 打赏
  • 举报
回复
真牛人也!!
lencail 2011-04-26
  • 打赏
  • 举报
回复
怎么还开发symbian??都要抛弃了
Edai9508 2011-04-25
  • 打赏
  • 举报
回复
Symbian c/s 机制分析
雷克斯 2011-04-24
  • 打赏
  • 举报
回复
挺厉害 但是 就是看不懂啊
lcwl00 2011-04-24
  • 打赏
  • 举报
回复
谢谢学习了
zlcp520 2011-04-24
  • 打赏
  • 举报
回复
内容存入剪贴板
lmc158 2011-04-24
  • 打赏
  • 举报
回复
有开发包吗?给个链接玩玩
singledrifter 2011-04-23
  • 打赏
  • 举报
回复
很好,呵呵
谭海燕 2011-04-23
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 lvyb030 的回复:]
原来塞班使用C++写的阿。
[/Quote]

So what?
It will die.
lvyb030 2011-04-23
  • 打赏
  • 举报
回复
原来塞班使用C++写的阿。
阿芙 2011-04-23
  • 打赏
  • 举报
回复
不错的文章
hanhan9 2011-04-23
  • 打赏
  • 举报
回复
好强 厉害
D380916607 2011-04-23
  • 打赏
  • 举报
回复
一直都对这个很感兴趣!谢谢LZ!
许文君 2011-04-22
  • 打赏
  • 举报
回复
有开发包吗?给个链接玩玩,谢谢
Joop_Song 2011-04-22
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 joop_song 的回复:]
这个是C#嘛???
[/Quote]

有点不像啊!!!!
Joop_Song 2011-04-22
  • 打赏
  • 举报
回复
这个是C#嘛???
加载更多回复(5)

3,120

社区成员

发帖
与我相关
我的任务
社区描述
塞班系统(Symbian系统)是塞班公司为手机而设计的操作系统,它的前身是英国宝意昂公司的 EP ( Electronic Piece of cheese)操作系统。
社区管理员
  • Symbian社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧