2013-04-29 30 views
1

我正在尝试使用Hoare的显示器实施证券交易所。使用显示器实施证券交易所

它有两个功能购买()和卖出()如下:

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

而且应该打印购买者ID,卖家ID,股票,股数和价格信息。 公平总是令人满意。

我的解决方案的伪代码如下,但它不完整。 它基本上为每个股票代码使用一个条件变量队列。卖方过程在向交易所发送卖出指令时被置于该队列中,并且如果满足条件(匹配的价格限制和股票数量),则买方过程向该卖方过程发出信号,表明其想要购买该过程。

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 
    } 
    } 
} 

这样的方法能够处理多个买卖双方的买卖订单吗?还是会导致死胡同?

+0

在我看来,这段代码可能会导致死锁的情况,因为您在等待之后增加了available_shares变量,所以买方将始终在条件和两者都失败,卖方和买方,永远等待 – 2013-04-29 13:33:49

+0

它最有可能。你知道我该如何解决这个问题吗?或者你能否提出一个不同的实施方案来实施这种证券交易所? – ratsimihah 2013-04-30 13:26:43

+0

@ladypada boost'lockfree' should help,but look out for http://stackoverflow.com/questions/14893246/trouble-with-boostlockfreequeue-in-shared-memory-boost-1-53-gcc-4-7- 2-CL btw:ty教我如何存储和处理订单。 – 2013-05-19 13:22:22

回答

2

要解决死锁问题,我会使用两个条件变量一个买方和一个卖方。每个方法首先修改available_shares,然后发送自己的条件变量,最后等待另一个条件变量。尽管如此,每次操作都需要在唤醒完成交易或再次入睡后重新检查有关available_shares的条件。

这里的问题是,这不会跟踪你从/向谁购买/销售多少。它甚至不保证卖方出售交易中的所有股份。所以,在回答你最初的问题时,我不明白这样的方法能够处理多个买卖人的多个买卖订单。我提出一种使用哈希表或dictionary,其中每个关键是限制这个其他解决方案,每个值是priority queue或由代号下令sorted 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); 
    } 
} 

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