我是C ++新手并尝试使用Pthread和Ncurses库。我正在制作节目,在终端屏幕上显示飞球。我创建了一个Ball类:
在文件Ball.h声明中,在Ball.c实现中。 Ball.h:
class Ball {
public:
//ATTRIBUTES
char sign;
int x, y, direction, speed, color;
int width, height; //area, field size
//CONSTRUCTORS
Ball();
~Ball();
Ball(int d, int s, int yy, int xx, int c, int fH, int fW);
//s - start direction, v - speed, x,y- position, c-color
//GETTERS
//METHODS
void setAreaSize(int, int);
void moveBall(void);
};
在其他文件中是我使用此类的程序:
.../*including some libs */...
.../*declaring some attributes */...
Ball *balls;
pthread_t *threads;
int howManyBalls;
int i; //helper for loops
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
struct timespec delay = { //our speed or rather delay ;)
1,
0
};
/* Function declarations */
void initBalls(void);
void initThreads(void);
void *threadBallFunction(void *arg);
//MAIN FUNCTION ----------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
... /*some code*/...
initBalls();
initThreads();
... /* some code */
return 0;
}
//FUNCTIONS IMPLEMENTATIONS ----------------------------------------------------------------------------------
/* INIT BALLS */
void initBalls(void){
balls = new Ball[howManyBalls]; //creating our balls array with appropriate size
int ballY, ballX, ballDirection, ballColor;
srand(time(0)); //resetting the random number generator
for(i=0;i<howManyBalls;i++){
ballY = (rand()%(frameWidth-1))-i;
ballX = (rand()%(frameHeight-1))-i;
ballDirection = rand()%8+1;
ballColor = rand()%7+1;
balls[i] = Ball(ballDirection,2,ballX,ballY,ballColor, frameHeight, frameWidth);
}
}
void *threadBallFunction(void *threadIndex) {
do{
/* WHAT HERE ?? */
}
while(1);
}
/* INIT THREADS */
void initThreads(void){
threads = new pthread_t[howManyBalls];
void *exit_status;
int threadIdx;
for (threadIdx = 0; threadIdx < howManyBalls; threadIdx++) {
pthread_create(&threads[threadIdx], NULL, threadBallFunction, &threadIdx);
pthread_join(threads[threadIdx], &exit_status);
}
}
所以,现在我想要那个球有自己的线程。所有线程都使用相同的函数 - threadBallFunction链接,在那里我只移动一个球,哪个球?它将通过传递给threadBallFunction的参数指定。球和线程应存储在单独的阵列中。球数由用户输入指定。移动球应该是无穷无尽的。
我不知道如何在这里使用互斥锁或条件变量...期待任何帮助,
的 //编辑: 更准确的问题:
我有许多线程链接到具有无限循环的相同函数。是否可以在此函数中使用条件变量同步线程的方法??
// EDIT2(谢谢艾哈迈德,但......) 好的,这对我很有帮助。非常感谢你;)buuuut让我说我希望线程无休止地工作并且每次增加时打印“计数器”值,每次增量或打印之间的时间应该是1秒。
例如:
counter = 0;
Thread1- IncCounterBy(2)
Thread2- IncCounterBy(5)
我的程序应该打印出来:
2(1秒后+2)
7(1秒后+5)
9(1秒后+2)
14(1秒后+5)
16(1秒后+2)
21(1秒后+5)
......直到我用CTRL + C停止它
如何管理?
亲切的问候
答案 0 :(得分:0)
互斥体也很容易被理解和使用, 假设你有一个班级
class A{
static int counter;
public:
static void IncCounterBy(int increment){
counter += increment;
}
};
假设有100个线程都在访问此函数,在任何时候2个线程 - 或者更多 - 可以同时访问同一个函数,每个线程都会复制原始值然后递增它 所以如果A :: counter是= 3
Thread1- IncCounterBy(2)
Thread2- IncCounterBy(5)
Thread3- IncCounterBy(1)
这将以=&gt;&gt;结尾A :: counter = 3;
如何使用Boost :: Mutex
class A{
static int counter;
boost::mutex Guard;
public:
static void IncCounterBy(int increment){
Guard.lock();
counter += increment;
Guard.unlock();
//Or you can use "boost::mutex::scoped_lock lock(Guard);" to guard a function
};
答案 1 :(得分:0)
您的具体问题:“是否可以在此函数中使用条件变量同步线程方法”
我仍然不清楚你真正要求的行为,所以让我们考虑两种情况:
答案是,对于此应用程序,条件变量不是正确的同步方法。条件变量实际上是指生产者消费者设计模式。特别是:
*如果cond上当前没有阻塞线程,则pthread_cond_broadcast()和pthread_cond_signal()函数不起作用。 http://linux.die.net/man/3/pthread_cond_signal *
您要求的是对共享状态对象(您的计数器)进行自动处理。在这种情况下,Ahmed是正确的,共享状态应该只是受互斥锁保护,以防止同时访问。
此更多案例与您的示例计数器增量流量相匹配。在这种情况下,只要线程数为2,就可以使用条件变量,并确保以确定的方式启动它们。有超过2个线程,除非它们具有不同的优先级,否则不能保证运行顺序。同样在这样的循环中启动它们并不能保证首先执行哪一个。
在这种情况下,一次只有一个线程工作,而其他所有线程都在等待。这不是多线程解决方案的理想选择。更好的模式是单个线程和工作队列。我的意思是创建一个所需的各种增量数量的循环队列,让一个线程在一个等待1秒的循环中运行,从队列中读取下一个增量,并递增计数器,递增队列指针,然后重复。