使用监视器实施证券交易所

时间:2013-04-29 01:25:43

标签: concurrency stock mutual-exclusion

我正在尝试使用Hoare的显示器实现股票交易。

它有两个函数buy()和sell()如下:

buy(procid, ticker, nshares, limit)
sell(procid, ticker, nshares, limit)

并且应该打印有关买方ID,卖家ID,股票代码,股票数量和价格的信息。 公平总是令人满意。

我的解决方案的伪代码如下,但它不完整。 它基本上为每个股票代码使用一个条件变量队列。当卖方进程向证券交易所发送卖单时,卖方进程就会在此队列中进入休眠状态;如果满足条件(匹配价格限制和股票数量),则买方进程会向卖方进程发出信号,表明它想要购买。 / p>

monitor SE {
  int available_shares;
  int price;

  sell(procid, ticker, nshares, limit) {
    wait(ticker); // put sell order in ticker queue
    available_shares += nshares;
    price = limit;
    printf("Starting transaction with seller %i", procid);
  }

  buy(procid, ticker, nshares, limit) {
    if (limit <= price && nshares <= available_shares) {
      signal(ticker);
      available_share -= nshares;
      printf("Completing transaction with buyer %i", procid);
      printf("Transacting %i %s shares at %i", nshares, ticker, limit);
    } else {
      wait(ticker); // put buy order in ticker queue
    }
  }
}

这种方法是否能够处理多个代码的多个买卖订单?还是会导致死胡同?

1 个答案:

答案 0 :(得分:2)

要解决死锁问题,我会使用两个条件变量,一个用于买方,一个用于卖方。每个方法首先修改available_shares,然后发出自己的条件变量信号,最后等待另一个条件变量。即使每个操作在唤醒完成事务或再次进入休眠状态后都必须重新检查有关available_shares的条件。

这里的问题是,这并没有跟踪你从谁购买/卖出多少。它甚至不保证卖方在交易中出售其所有股份。因此,在回答您的原始问题时,我不知道这种方法如何能够处理多个代码的多个买卖订单。我建议使用HashTable或dictionary的其他解决方案,其中每个键都是一个限制,每个值都是由代码排序的priority queuesorted list

monitor SE {
  int available_shares;
  int price;
  Dictionary<int, SortedList<int, Transac>> Ts;

  sell(procid, ticker, nshares, limit) {
    Transac t = new Transac(procid, nshares, limit);

    Ts[limit].enqueue(ticker, t); //probably you should verify first if the entry is not null 

    available_shares += nshares;

    notifyAll(tickerB);

    while(Ts[limit][ticker] > 0)
      wait(tickerS); 

    printf("Starting transaction with seller %i", Ts[limit][ticker].procid);
  }

  buy(procid, ticker, nshares, limit) {

    int nshares_copy = nshares;

    while(true){
      int cnt = 0;
      List<Transac> tmp = new List<Transac>();
      for(int i = 0; i < Ts.keys.length && cnt < nshares; i++){
          if(Ts.keys[i] <= limit){
            for(int j = 0; j < Ts[Ts.keys[i]].lenght && cnt < nshares; j++){
                cnt += Ts[Ts.keys[i]][j].nshares;
                tmp.add(Ts[Ts.keys[i]][j]);
            }
          }
      }
      if(nshares <= cnt){
          available_share -= nshares;

          foreach(Transac t in tmp){
            int min = min(t.nshares, nshares);
            t.nshares -= min;
            nshares -= min;
          }
          break;
      } else {
          wait(tickerB);
      }
    }

    notifyAll(tickerS);

    printf("Completing transaction with buyer %i", procid);
    printf("Transacting %i %s shares at %i", nshares_copy, ticker, limit);
  }
}

我这样做是使用显示器来跟随你最初的想法,但我不得不说我不认为这是最好的方式。我认为更细粒度的锁可以为您提供更好的性能(例如锁或原子操作)。 注意:代码尚未经过测试。所以,我可能遗漏了一些实现细节