C ++ - Pthread,多个线程与一个具有无限循环的函数相关

时间:2013-01-15 22:28:10

标签: c++ multithreading loops pthreads infinite-loop

我是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停止它

如何管理?

亲切的问候

2 个答案:

答案 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)

您的具体问题:“是否可以在此函数中使用条件变量同步线程方法”

我仍然不清楚你真正要求的行为,所以让我们考虑两种情况:


案例1:您希望线程自主运行,并且每个线程在其自己的预定时间段内独立更新计数器:

答案是,对于此应用程序,条件变量不是正确的同步方法。条件变量实际上是指生产者消费者设计模式。特别是:

*如果cond上当前没有阻塞线程,则pthread_cond_broadcast()和pthread_cond_signal()函数不起作用。 http://linux.die.net/man/3/pthread_cond_signal *

您要求的是对共享状态对象(您的计数器)进行自动处理。在这种情况下,Ahmed是正确的,共享状态应该只是受互斥锁保护,以防止同时访问。

案例2:您希望每个线程进行某种循环处理,其中一个线程运行,等待1秒,然后按参数量更新计数器。然后下一个线程运行,等待1秒钟,并按其不同的参数量更新计数器。依此类推,直到你回到第一个线程。

此更多案例与您的示例计数器增量流量相匹配。在这种情况下,只要线程数为2,就可以使用条件变量,并确保以确定的方式启动它们。有超过2个线程,除非它们具有不同的优先级,否则不能保证运行顺序。同样在这样的循环中启动它们并不能保证首先执行哪一个。

在这种情况下,一次只有一个线程工作,而其他所有线程都在等待。这不是多线程解决方案的理想选择。更好的模式是单个线程和工作队列。我的意思是创建一个所需的各种增量数量的循环队列,让一个线程在一个等待1秒的循环中运行,从队列中读取下一个增量,并递增计数器,递增队列指针,然后重复。