ICE实现线程安全之互斥

如果在一个线程读取某个数据结构的同时,另一个线程正在更新同一个数据结构,
除非你用适当的锁保护这个数据结构,否则就会发生严重的混乱。



线程模型
Ice服务器天生是多线程的。服务器端run time维护有一个线程池,用于处理到来的请求。
通过领导者-跟随者(leader-follower)线程模型,
客户发来的每个操作调用都会在其自己的线程中被分派。在服务器中,如果所有线程都在执行操作调用,耗尽了线程池,随后到来的客户请
求就会“透明地”延迟处理,直到服务器中的某个操作完成、放弃其线程;这个线程随即被用于分派下一个待处理的客户请求。
通过Ice.ThreadPool.Server.Size属性,可以配置服务器中的线程池的尺寸。

多线程意味着,来自客户的多个调用可以在服务器中并发执行。事实上,在同一个
servant中,以及在同一servant的同一个操作中,都可以有多个请求在并行执行。因此,如果在操作实现中,涉及到对非栈存储的操纵
(比如servant的成员变量、全局变量,或静态变量),你必须对数据访问进行互锁,以防止数据损坏。


//不要从同一个线程多次针对同一个互斥体调用
namespace IceUtil {//简单的非递归互斥机制
    class Mutex {
    public:
        Mutex();
        ~Mutex();
        void lock() const;
        bool tryLock() const;
        void unlock() const;
        typedef LockT Lock;
        typedef TryLockT TryLock;
    };
    struct StaticMutex {
        void lock() const;
        bool tryLock() const;
        void unlock() const;
        typedef LockT Lock;
        typedef TryLockT TryLock;
    };
}


文件系统服务器的read和write操作的实现不是线程安全的:
Filesystem::Lines Filesystem::FileI::read(const Ice::Current &) const
{
    return _lines;      // Not thread safe!
}
void Filesystem::FileI::write(const Filesystem::Lines & text,const Ice::Current &)
{
    _lines = text;      // Not thread safe!
}


这些代码的问题在于,如果我们收到对read和write的并发调用,
一个线程就会向_lines向量赋值,而另一个线程正读取该向量。这样的
并发数据访问产生的结果是不确定的;要避免发生这样的问题,我们需要通过互斥体,使对_lines
成员的访问序列化。我们可以让这个互斥体成
为FileI类的数据成员,并在read和write操作中对它进行加锁和解锁:

namespace Filesystem {
    // ...
    class FileI : virtual public File,
        virtual public Filesystem::NodeI {
    public:
        // As before...
    private:
        Lines _lines;
        IceUtil::Mutex _fileMutex;
    };
    // ...
}
Filesystem::Lines Filesystem::FileI::read(const Ice::Current &) const
{
    _fileMutex.lock();
    Lines l = _lines;
    _fileMutex.unlock();
    return l;
}
void Filesystem::FileI::write(const Filesystem::Lines & text,
                         const Ice::Current &)
{
    _fileMutex.lock();
    _lines = text;
    _fileMutex.unlock();
}

你可能感兴趣的:(客户端代理),ICE(服务器适配,客户端代理),ICE(服务器适配,客户端代理))