免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: die
打印 上一主题 下一主题

一个正在开发中的异步网络库 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-02-11 00:31 |只看该作者
>> 所以我的函数库里,Cond自己创建锁。
Cond自己创建锁也是可以的,C#提供了Monitor类就是这样做的,但是上面的橘子苹果的用法并不正确。

下面是C#的实现供你参考:
Monitor是mutex和condtion的组合
class Monitor {
     pthread_mutex_t mutex;
     pthread_condtion_t cond;

public:
     lock和unlock方法必须暴露出来
     void  lock()
     {
           pthread_mutex_lock(&mutex);
     }

     void unlock()
     {
           pthread_mutex_unlock(&mutex);
     }

     void wait()
     {
           pthread_cond_wait(&cond, &mutex);
     }
   
     void signal()
     {
           pthread_cond_signal(&cond);
     }
}


C#中使用Monitor的模式是:
Monitor monitor; Monitor是mutex和condtion的组合

monitor.lock();
wait不需要有mutex参数了,但是monitor.cond仍然是受到monitor.mutx的保护
while (期待的条件 == FALSE)
      monitor.wait();  

assert(期待的条件 == 真);
do somthing;

monitor.unlock();


C语言中使用conditon的模式:

  1. mutex.lock();
  2. while (期待的条件 == FALSE)
  3.       condition.wait(&mutex);

  4. assert(期待的条件 == 真);
  5. do somthing;

  6. mutex.unlock();
复制代码

把C#的代码展开后,可以发现C#的方法和传统POSIX的方法原理上是完全一样的,总之,condition也是共享资源,和fruits一样,也需要受到mutex的保护,禁止多个线程同时访问。

[ 本帖最后由 CRLF 于 2009-2-11 00:36 编辑 ]

论坛徽章:
0
12 [报告]
发表于 2009-02-11 00:35 |只看该作者
#ifndef  COND_HPP
#define  COND_HPP

//
// Cond.hpp
// ~~~~~~~~~~~~~~~~
//
// @author <zhuxueling@pica.com>
// @data   2009-02-05

#include <pthread.h>
#include "Lock.hpp"
#include "Mutex.hpp"

namespace Traxex{
class Cond{
public:
    Cond():lock_( mutex_){
        int stat = pthread_cond_init( &cond_, 0);
        if( stat !=0 ){
            throw Error( COND_CREATE_ERR);
        }
    }
    virtual ~Cond(){
        pthread_cond_destroy( &cond_);
    }

    bool wait( bool lock = true){
        if( lock){
            bool stat = lock_.do_lock();
            if( !stat) return false;
        }
       
        int wait_stat = pthread_cond_wait( &cond_,& mutex_.mutex_);

        if( lock){
            lock_.unlock();
        }
        if( wait_stat != 0) return false;
        return true;
    }
   
    bool time_wait( double sec, bool lock = true){
        if( lock){
            bool stat = lock_.do_lock();
            if( !stat) return false;
        }

        int  sec_  = (int)( sec);
        int  nsec_ = (int)( (sec * 1000000) - sec_ * 1000000);
        timespec timeout={ sec_, nsec_};
        int wait_stat = pthread_cond_timedwait( &cond_, &mutex_.mutex_, &timeout);

        if( lock){
            lock_.unlock();
        }
        if( wait_stat != 0) return false;
        return true;
    }
    bool signal( bool one = true){
        int stat;
        if( one){
            stat = pthread_cond_signal( &cond_);
        }else{
            stat = pthread_cond_broadcast( &cond_);
        }
        if( stat !=0 ) return false;
        return true;
    }

    bool lock(){
        return lock_.do_lock();
    }
    bool unlock(){
        return lock_.unlock();
    }
private:
    Mutex                mutex_;
    Lock                lock_;
    pthread_cond_t        cond_;
};
};
#endif   //COND_HPP

[ 本帖最后由 die 于 2009-2-11 00:40 编辑 ]

论坛徽章:
0
13 [报告]
发表于 2009-02-11 00:41 |只看该作者
原帖由 die 于 2009-2-11 00:23 发表
ScopeLock lock( mutex);
这个不是一个局部锁么。。。
出作用域自动解锁的。

但是下面的代码中,有可能出现add线程执行cond.signal、eat线程执行cond.wait的情况,cond和fruits vector一样都是属于共享资源,不能被多个线程同时访问。
void add(string name){
    while( true){
        ScopeLock lock( mutex);
        fruits.push(name);
        std::cout << "add " << name << std::endl;
        执行到这里:cond.signal(); cond是共享资源!
        Sleep( 200);
    }
}

void eat( ){
    while( true){
        执行到这里:cond.wait(); cond是共享资源!
        ScopeLock lock( mutex);
        fruits.pop();
        std::cout << "eat "<< fruits.front() << std::endl;
    }
}

[ 本帖最后由 CRLF 于 2009-2-11 00:43 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2009-02-11 00:45 |只看该作者
最近正好研究这个问题,同步的问题比较复杂,大家一起来讨论,希望能搞清楚它的用法。

论坛徽章:
0
15 [报告]
发表于 2009-02-11 00:47 |只看该作者
原帖由 CRLF 于 2009-2-11 00:41 发表

但是下面的代码中,有可能出现add线程执行cond.signal、eat线程执行cond.wait的情况,cond和fruits vector一样都是属于共享资源,不能被多个线程同时访问。

在任何操作中,Cond都是对成员的只读操作,为什么要加锁?
vector己经加锁了,请注意。

论坛徽章:
0
16 [报告]
发表于 2009-02-11 00:50 |只看该作者
如果觉得condition是共享资源不好理解的化,可以看下LINUX中pthread_cond_t的数据结构:

  1. /* Conditions (not abstract because of PTHREAD_COND_INITIALIZER */
  2. typedef struct {
  3.       int c_spinlock;                  /* Spin lock to protect the queue.  */
  4.       struct _pthread_queue c_waiting;  /* Threads waiting on this condition.  */
  5. } pthread_cond_t;

  6. struct _pthread_queue {
  7.     _pthread_descr_struct  *head;          /* First element, or NULL if queue empty.  */
  8.     _pthread_descr_struct  *tail;          /* Last element, or NULL if queue empty.  */
  9. };
复制代码

pthread_cond中的数据结构中包含有一个链表,显然,若有两个线程同时访问同一个cond变量的化,就会出现问题。

在任何操作中,Cond都是对成员的只读操作,为什么要加锁?
vector己经加锁了,请注意。

pthread_cond_wait会把当前线程的pthread_descr加入到cond的链表中,而pthread_cond_signal会从cond的链表中删除一个节点。

[ 本帖最后由 CRLF 于 2009-2-11 00:52 编辑 ]

论坛徽章:
0
17 [报告]
发表于 2009-02-11 00:50 |只看该作者
还有,一个Cond的设计,还要手写代码去加锁保护,那不是一个失败的设计么。。

ps: 那个wait和cond,都会用cond里那个锁对象对锁自身的。

[ 本帖最后由 die 于 2009-2-11 01:00 编辑 ]

论坛徽章:
0
18 [报告]
发表于 2009-02-11 08:52 |只看该作者
支持楼主的行为

论坛徽章:
0
19 [报告]
发表于 2009-02-11 09:58 |只看该作者
原帖由 die 于 2009-2-10 23:07 发表
接触Linux有一年了吧,总觉得的Posix线程,锁,条件变量,不方便,
创建线程的参数是不是应该多变一些呢?为啥不让我用类的成员函数?
(我水平一般,或者说还很菜,要不然怎么会没工作?)
还没有线程池,还 ...


你要做的我已经写过了好像, 不信你看看是不是, 我用C写的,也是面相对象的

http://sbase.googlecode.com/

论坛徽章:
0
20 [报告]
发表于 2009-02-11 13:59 |只看该作者
你在做我做过的事,而我在做别人做过的事。哈哈
有意思!
不过值得鼓励,相互学习,相互提高!

我的可参见我的签名。但不要下载了,下载的还是1.0.0版的,过两周1.4.0版的下载就会放出来了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP