使用PThreads进行全局列表访问 - 指针问题?

时间:2011-12-08 16:12:23

标签: c++ c pointers pthreads

我们正在使用线程和互斥体来模拟一群客户点击不同或相同的银行账户。我几乎没有C / C ++经验,我认为这个问题与指针有关。基本上我有一个Client对象,它包含一个事务列表和一个帐户列表,并作为参数传递给pthread,并将其发送到处理方法。

class Client{
public:
    list<Transaction> transactions;
    list<Account>* accounts;
    Client(list<Transaction>, list<Account>);
};

Client::Client(list<Transaction> a, list<Account> b){
transactions = a;
accounts = &b;
}

extern "C"
{
void* RunTransactions(void* arg)
{
    Client* c = static_cast<Client*>(arg);

    // while(!(*c).transactions.empty()){
        // cout << "HERE" << endl;
    // }

    cout << "Thread Before: ";
    (*(*c).accounts).front().Print();

    (*(*c).accounts).front().balance -= 25;
    (*(*c).accounts).front().balance -= 25;
    (*(*c).accounts).front().balance -= 25;

    cout << "Thread After: ";
    (*(*c).accounts).front().Print();

    // list<Transaction>* trans = static_cast<list<Transaction>*>(arg);
    // Transaction t = trans->front();
    // t.Print();

    // Test* t = static_cast<Test*>(arg);

    // (*t).Increase();
    // cout << "Thread - " << t->x << endl;

    return 0;
}
}

int main( ){

list<Account> accounts;

cout << "Accounts: ";
cin >> NumAccts;

for(long i = 0; i < NumAccts; i++){
    long tempBalance;
    cout << "Balance for Account " << i << ": ";
    cin >> tempBalance;

    accounts.push_back(Account(i, tempBalance));
}

//Test Input
pthread_t t1;
list<Transaction> tempTrans;
tempTrans.push_back(Transaction(0, 1, 100));
tempTrans.push_back(Transaction(1, 0, 50));
tempTrans.push_back(Transaction(2, 1, 222));

Client c = Client(tempTrans, accounts);

cout << "Main Before: ";
accounts.front().Print();

pthread_create(&t1, NULL, RunTransactions, &c);

pthread_join(t1, NULL);

cout << "Main After: ";
accounts.front().Print();


return 0;
}

我不明白的是我应该如何让我的线程都可以访问在main中创建的帐户列表?现在,每当我从客户端执行任何操作时,我都会从客户端执行任务,它会在线程中进行更改,但是在加入后我看不到主帐户列表中的更改。同样,我认为这与我传递或访问Client对象或main中的帐户,或者可能是RunTransactions的方式有关?任何建议将不胜感激!

2 个答案:

答案 0 :(得分:1)

Client::Client(list<Transaction> a, list<Account> b) {

b是传入列表的副本,几乎肯定会在堆栈上传递。一旦构造函数返回,您的指针可能就无效了。

您最好将客户的accounts设为实际列表,而不是指向其中的指针。你真的不想让你的对象持有指向未分配堆的东西或其他人有权访问的东西的指针。那种方式就是疯狂。

答案 1 :(得分:0)

Client::Client(list<Transaction> a, list<Account> b){
    transactions = a;
    accounts = &b;
}

基本上是在说:“哦,是的,罗伊,你有这个清单,对,所有这些帐户?好吧,有人通过电子邮件发给我,你能看到那个清单来自哪里,只是存储谁的名字创建了列表?我确信我们以后能够从该地址返回列表。“

所以Roy在客户的个人资料中存储了“Waldo”这个名字。我们都知道那之后发生了什么。可悲的是,当客户要求时,他再也无法取回列表。如果他只是制作了一份清单,或确保创建清单的来源不会在某一天消失。