C++线程程序未运行完成

C++ pThread program isn't running to completion

本文关键字:运行 线程 程序 C++      更新时间:2023-10-16

我有一个奇怪的问题,即我的C 多线程程序无法完成。它应该运行num_threads -1次。任何帮助我指向正确方向的资源将不胜感激!目前,这些是重要的功能

int main(void) {
int ret;
//Threads + current thread tracker
pthread_t threads[NUM_THREADS]; int j = 0;
int num_transacts = 0;  bool isBuy = true;
srand(time(NULL));
Stock MSFT("MSFT"); stocks.push_back(MSFT);
Stock AMZN("AMZN"); stocks.push_back(AMZN);
Stock BAC("BAC"); stocks.push_back(BAC);
Stock NKE("NKE"); stocks.push_back(NKE);
//Buys or Sells for NUM_THREADS - 1 times
while (num_transacts < NUM_THREADS) {
    if (isBuy) {
        //Percent chance to buy
        if (((double)rand() / (double)RAND_MAX) < Z) {
            cout << "Making buy thread.n";
            pthread_mutex_lock(&mLock);
            ret = pthread_create(&threads[j], NULL, buy, NULL);
            if (ret != 0) {
                cout << "Thread failed at Buy Thread Create.n";
            }
            pthread_mutex_unlock(&mLock);
            cout << "BuyNumTrans: " << num_transacts << "n";
            ++j;
            ++num_transacts;
            isBuy = false;
        }
    }
    else {
        if (bought.size() > 0) {
            //Percent chance to sell if it has increased or decreased too much in price
            int s = rand() % bought.size();
            if ((bought.at(s).checkPrice()) > (((1 + X)*bought.at(s).getCost())) || (bought.at(s).checkPrice()) < (((1 + Y)*bought.at(s).getCost()))) {
                cout << "Making sell thread.n";
                pthread_mutex_lock(&mLock);
                ret = pthread_create(&threads[j], NULL, sell, (void*) &s);
                if (ret != 0) {
                    cout << "Thread failed at Sell Thread Create.n";
                }
                pthread_mutex_unlock(&mLock);
                cout << "SellNumTrans: " << num_transacts << "n";
                ++j;
                ++num_transacts;
            }
            //Gets a new price possibility
            bought.at(s).getPrice();
        }
        isBuy = true;
    }
}
for (int i = 0; i < NUM_THREADS; ++i) {
    pthread_join(threads[i], NULL);
}
return 0;
}
pthread_mutex_t mLock;
pthread_mutex_t bLock;
pthread_mutex_t sLock;
vector<Stock> stocks;
vector<Stock> bought;
int balance = 1000000, yield = 0, profit = 0, Tcost = 0;
//In format  BUY MSFT 100 35.2
//In format  SELL MSFT 80 45
void* processTransact(void* argument) {
    string* arg = (string*)argument;
    istringstream iss(*arg);
    vector<string> words{ istream_iterator<string>(iss), istream_iterator<string> {} };
    if (words.front() == "BUY") {
        words.erase(words.begin());
        //gets the symbol name
        string symbol = words.front();
        words.erase(words.begin());
        //gets num of stocks to buy
        string a = words.front();
        int buyNum = atoi(a.c_str());
        words.erase(words.begin());
        //gets the price per share
        a = words.front();
        int sharePrice = atoi(a.c_str());
        //update num_shares, cost, balance, and Tcost
        Stock newBuy(symbol, buyNum, sharePrice);
        balance -= (buyNum * sharePrice);
        bought.push_back(newBuy);
        cout << "Bought stock... " << balance << endl;
        pthread_exit(NULL);
    }
    else {
        words.erase(words.begin());
        //gets the symbol name
        string symbol = words.front();
        words.erase(words.begin());
        //gets num of stocks to sell
        string a = words.front();
        int buyNum = atoi(a.c_str());
        words.erase(words.begin());
        //gets the price per share
        a = words.front();
        int sharePrice = atoi(a.c_str());
        a = words.front();
        int s = atoi(a.c_str());
        //update num_shares, cost, balance, and Tcost
        balance += (buyNum * sharePrice);
        bought.erase(bought.begin() + s);
        cout << "Sold stock... " << balance << endl;
        pthread_exit(NULL);
    }
    sleep(2);
}
void* buy(void*) {
    pthread_mutex_lock(&mLock);
    pthread_t thread;
    srand(time(NULL));
    int ret;
    int i = rand() % stocks.size();
    //Creates a string that processTransact can parse
    string transactString = "BUY " + stocks.at(i).getName() + " 100 " + to_string(stocks.at(i).getPrice());//make transaction string
    ret = pthread_create(&thread, NULL, processTransact, (void*)&transactString);
    if (ret != 0) {
        cout << "Error in buy thread process create.n";
    }
    pthread_join(thread, NULL);
    pthread_mutex_unlock(&mLock);
    pthread_exit(NULL);
}
void* sell(void* argument) {
    pthread_mutex_lock(&mLock);
    pthread_t thread;
    int ret, s = *((int*)argument);;
    //Creates a string that processTransact can parse
    string transactString = "SELL " + bought.at(s).getName() + " 100 " + to_string(bought.at(s).getPrice()) + to_string(s);//make transaction string
    ret = pthread_create(&thread, NULL, processTransact, (void*)&transactString);
    if (ret != 0) {
        cout << "Error in sell thread process create.n";
    }
    pthread_join(thread, NULL);
    pthread_mutex_unlock(&mLock);
    pthread_exit(NULL);
}

在上面的代码中,我在bought变量访问中看到了潜在的未定义行为问题。这可能是您问题的原因。

while循环中有行:

if (bought.size() > 0) {
  //Percent chance to sell if it has increased or decreased too much in price
  int s = rand() % bought.size();

void* processTransact(void* argument)功能中:

bought.push_back(newBuy);
// Code skipped ....  
bought.erase(bought.begin() + s);

processTransact代码在单独的线程中修改bought的大小。在while中,循环访问bought.size()与使用mLock MUTEX不会同步。这意味着在bought.size() > 0验证后,您可能会获得空的bought矢量。它导致rand() % 0的不确定行为。

此外,当修改相同的容器(bought)并从不同的线程读取时,C 标准不能保证线程安全性。