/* File: ~liux/public_html/courses/cop4610/examples/simple-thread.cc
Purpose: Demonstrate how to create multiple threads in UNIX
for COP 4610
Author: Xiuwen Liu
On the web:
http://www.cs.fsu.edu/~liux/courses/cop4610/examples/simple-thread.cc
Command to complie (Pay attention to -lthread):
g++ -o simple-thread simple-thread.cc -lthread
Special note:
You can only compile and run this program on "program"
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NUM_THREADS 5
thread_t tid[NUM_THREADS]; /* array of thread IDs */
int performed_transactions[NUM_THREADS];
int totalTransaction;
int accounts[NUM_THREADS]; /* Account balances */
void * RandomTransaction(void *msg);
int PerformATransaction(int from, int to, int val);
int CheckRunning(void);
int main(int argc, char *argv[])
{
int i, sum;
totalTransaction = 0;
for (i=0; i < NUM_THREADS; i++) {
accounts[i] = 1000;
performed_transactions[i] = 0;
}
sum =0;
for (i=0; i< NUM_THREADS; i++) {
cout << "\n\tInit account "
<< i+1 << "'s balance: " << accounts[i];
sum += accounts[i];
}
cout <<"\n\tTotal initial balance is " << sum << endl;
for (i=0; i < NUM_THREADS; i++) {
if (thr_create(NULL, (int)0, RandomTransaction, (char *)NULL,
THR_SUSPENDED, &(tid[i])) <0) {
perror("create thread: ");
return -1;
}
}
for (i=0; i < NUM_THREADS; i++)
thr_continue(tid[i]);
while (thr_join((thread_t)NULL,
(thread_t *)NULL, (void **)NULL) == 0);
for (i=0; i < NUM_THREADS; i++) {
cout << "\nAccount " << i+1 << " performed "
<< performed_transactions[i];
}
cout << "\n";
return 0;
}
void * RandomTransaction(void *msg)
{
thread_t current_thr;
int myAcct, toAcct;
int amount;
current_thr = thr_self();
for (myAcct=0; myAcct < NUM_THREADS; myAcct++) {
if (current_thr == tid[myAcct]) break;
}
if (myAcct >= NUM_THREADS) {
cerr << "Something must be wrong with the thread IDs.\n";
return (void *)NULL;
}
cout << "Thread " << myAcct+1 << " is running.\n";
do {
/* First figure out my account number */
do {
toAcct = ((int)random())%NUM_THREADS;
} while (myAcct == toAcct);
amount = (int)(random()%10+10);
PerformATransaction(myAcct, toAcct, amount);
} while(CheckRunning());
return (void *)NULL;
}
int PerformATransaction(int from, int to, int val)
{
int i, sum;
if (accounts[from] < val) {
thr_yield();
return -1;
}
performed_transactions[from]++;
accounts[from] -= val;
thr_yield();
accounts[to] += val;
totalTransaction++;
if ((totalTransaction %100000) == 0) {
sum =0;
cout << "\nNow "
<< totalTransaction
<< " transactions have been completed.";
for (i=0; i<5; i++) {
cout << "\n\tAccount " << i+1
<< "'s balance: " << accounts[i];
sum += accounts[i];
}
cout << "\n\tTotal balance after "
<< totalTransaction
<< " transactions is " << sum << endl;
}
return 0;
}
int CheckRunning(void)
{
int i;
i = (int)(totalTransaction < 1000000);
return i;
}