【发布时间】:2012-11-10 18:37:22
【问题描述】:
这是主要代码的示例(“Library/stack.h”并不重要,但无论如何,它是this previous question of mine中包含的最后一个源):
#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <tinythread.h>
#include "Library/stack.h"
using namespace std;
using namespace tthread;
#define BOULDERspd 100
// ========================================================================= //
struct Coord {
int x, y;
};
int randOneIn (float n) {
return ((int) (n * (rand() / (RAND_MAX + 1.0))));
}
int randOneIn (int n) {
return ((int) ((float) n * (rand() / (RAND_MAX + 1.0))));
}
// ========================================================================= //
#include <windows.h>
void gotoxy (int column, int line) {
if ((column >= 0) && (line >= 0)) {
COORD coord;
coord.X = column;
coord.Y = line;
SetConsoleCursorPosition(
GetStdHandle( STD_OUTPUT_HANDLE ),
coord
);
}
}
void gotoxy (Coord pos) {
gotoxy(pos.x, pos.y);
}
// ========================================================================= //
void render (char image, Coord pos) {
gotoxy(pos);
cout << image;
}
void unrender (Coord pos) {
gotoxy(pos);
cout << ' ';
}
// ========================================================================= //
char randimage (void) {
return (rand() % 132) + 123;
}
mutex xylock;
class Boulder {
char avatar;
Coord pos;
public:
Boulder (int inix) {
pos.x = inix;
pos.y = 0;
avatar = randimage();
};
void fall (void) {
unrender(pos);
pos.y++;
render(avatar, pos);
Sleep(BOULDERspd);
};
void live (void) {
do {
fall();
} while (y() < 20);
die();
};
void die (void) {
unrender(pos);
pos.y = 0;
};
int x (void) { return pos.x; };
int y (void) { return pos.y; };
};
// ========================================================================= //
class thrStack: public Stack<thread*> {
public:
thrStack (): Stack<thread*> () { };
void pushNrun (thread* elem) {
push(elem);
top->core->joinable();
}
};
void randBoulder (void* arg) {
srand(time(NULL));
Boulder boulder(rand() % 40);
boulder.live();
}
void Boulders (void* arg) {
srand(time(NULL));
thrStack stack;
do {
stack.pushNrun(new thread (randBoulder, 0));
Sleep(rand() % 300);
} while(1);
}
// ========================================================================= //
// ========================================================================= //
int main() {
thread raining (Boulders, 0);
raining.join();
}
我是多线程的新手,所以为了摆弄它,我正在尝试制作一个程序,让随机字符不断从屏幕顶部掉下来,就好像在下雨一样 ASCII 符号。
不过,我注意到我的编码中有一点(大)错误:
bool xylock = false;
class Boulder {
char avatar;
Coord pos;
public:
Boulder (int inix) {
pos.x = inix;
pos.y = 0;
avatar = randimage();
};
void fall (void) {
unrender(pos);
pos.y++;
render(avatar, pos);
Sleep(BOULDERspd);
};
void live (void) {
do {
fall();
} while (y() < 20);
die();
};
void die (void) {
unrender(pos);
pos.y = 0;
};
int x (void) { return pos.x; };
int y (void) { return pos.y; };
};
因为 fall() 函数使用了 gotoxy,它会改变“全局光标”,多次调用 gotoxy 会打乱程序的预期执行。如果您尝试按原样编译代码,您会得到不断变换位置并留下垃圾的掉落字母。
有没有什么方法可以使用或实现一个锁来解决这个和未来的情况,就像 TinyThread 一样? C++中锁的实现逻辑一般是什么?
编辑:修改 fall();没事吧,驯鹿?
void fall (void) {
lock_guard<mutex> guard(xylock);
unrender(pos);
pos.y++;
render(avatar, pos);
xylock.unlock();
Sleep(BOULDERspd);
};
【问题讨论】:
-
你从哪里开始线程?我是否遗漏了您的代码中的某些内容?
-
@marscode 在 main() (在第一个源中找到,但在后者中没有),我创建了一个调用 void Boulders (void* arg) 函数的线程。该函数依次实例化一个线程堆栈(通过 thrStack 堆栈),并不断将调用 void randboulder 的新线程推入该堆栈以供它们运行。
标签: c++ multithreading locking race-condition