简体   繁体   English

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

[英]C++ - Pthread, Multiple Threads related to one function with endless loop

I am C++ newbie and try to work with Pthread and Ncurses libraries. 我是C ++新手,尝试使用Pthread和Ncurses库。 I am making program, which displays flying balls in the terminal screen. 我正在编写程序,该程序在终端屏幕上显示飞球。 I created a Ball class: 我创建了一个Ball类:

In file Ball.h declaration, in Ball.c implementation. 在文件Ball.h声明中,在Ball.c实现中。 Ball.h : 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);
};

In other file is my program which uses this class: 在其他文件中是我的程序使用此类:

.../*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);
    }
}

So, now I want that ever ball has its own thread. 所以,现在我希望那个球有自己的螺纹。 All threads are linked with the same function - threadBallFunction, where I will move only one ball, which ball? 所有线程都用同一个函数-threadBallFunction链接,在这里我将只移动一个球,哪个球? it will be specified by argument passed to threadBallFunction. 它由传递给threadBallFunction的参数指定。 Balls and Threads should be stored in separate arrays. 球和线应存储在单独的数组中。 Number of balls is specified by user input. 球数由用户输入指定。 Moving balls should be endless. 移动球应该是无止境的。

I dont know how to use Mutexes or Condition Variables here... looking forward for any help, 我不知道如何在此处使用互斥对象或条件变量...期待任何帮助,

//EDIT: More precised question: //编辑:更精确的问题:

I have many threads linked to the same function with endless loop. 我有很多线程通过无限循环链接到同一功能。 Is it possible to use in this function Condition Variable method of synchronization threads?? 是否可以在此函数中使用同步线程的条件变量方法?

//EDIT2 (Thank You Ahmed but...) Ok, it is really helpful for me. // EDIT2(谢谢艾哈迈德,但...)好的,这对我真的很有帮助。 Thank you very much ;) buuuut lets say I want threads working endless and printing the "counter" value every time it is incremented, time between each incrementation or printing should be 1 sec. 非常感谢;)buuuut可以说我希望线程无休止地工作,并在每次递增时打印“ counter”值,每次递增或打印之间的时间应为1秒。

For example: 例如:

counter = 0; 计数器= 0;

Thread1- IncCounterBy(2) 线程1- IncCounterBy(2)

Thread2- IncCounterBy(5) 线程2- IncCounterBy(5)

and my program should print: 并且我的程序应打印:

2 (+2 after 1sec) 2(1秒后+2)

7 (+5 after 1sec) 7(1秒后+5)

9 (+2 after 1sec) 9(1秒后+2)

14 (+5 after 1sec) 14(1秒后+5)

16 (+2 after 1sec) 16(1秒后+2)

21 (+5 after 1sec) 21(1秒后+5)

... till I stop it with CTRL+C ...直到我用CTRL + C停止

How to manage this? 如何处理?

kind regards 亲切的问候

Mutexes are very easy to be understood and used as well, Let's say you have a class 互斥体也很容易理解和使用,假设您有一类

class A{
        static int counter;
    public:
        static void IncCounterBy(int increment){
            counter += increment;
        }
    };

Assume there is 100 threads all are accessing this function, at any time 2 threads -or more- may access the same function at the same time, each will copy the original value then increment it so if A::counter was = 3 假设有100个线程都在访问该函数,则随时有2个线程(或更多线程)可以同时访问同一函数,每个线程将复制原始值,然后将其递增,因此如果A :: counter = 3

Thread1- IncCounterBy(2) 线程1- IncCounterBy(2)

Thread2- IncCounterBy(5) 线程2- IncCounterBy(5)

Thread3- IncCounterBy(1) 线程3- IncCounterBy(1)

this will end in =>> A::counter = 3; 这将以= >>结尾:A :: counter = 3;

How to use Boost::Mutex 如何使用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
    };

Your specific question: "Is it possible to use in this function Condition Variable method of synchronization threads" 您的特定问题:“是否可以在此函数中使用条件变量同步线程方法”

I am still unclear as to the behavior you are really asking for so lets consider both cases: 对于您真正要求的行为,我仍然不清楚,因此让我们考虑两种情况:


Case 1: You want the threads running autonomously and each independently updating the counter on its own scheduled period: 情况1:您希望线程自主运行,并且每个线程都在自己的预定时间段内独立更新计数器:

The answer is that for this application, condition variables are not the correct method of synchronization. 答案是,对于此应用程序,条件变量不是正确的同步方法。 Condition variables are really meant for the producer consumer design pattern. 条件变量实际上是针对生产者消费者设计模式的。 In particular: 尤其是:

*The pthread_cond_broadcast() and pthread_cond_signal() functions shall have no effect if there are no threads currently blocked on cond. *如果cond上当前没有阻塞的线程,则pthread_cond_broadcast()和pthread_cond_signal()函数无效。 http://linux.die.net/man/3/pthread_cond_signal * http://linux.die.net/man/3/pthread_cond_signal *

What you are asking for is autonomous processing on a shared state object (your counter). 您需要的是对共享状态对象(您的计数器)进行自主处理。 In this case Ahmed is correct in that the shared state should simply be protected by a mutex to prevent simultaneous access. 在这种情况下,艾哈迈德(Ahmed)是正确的,因为共享状态应仅由互斥对象保护,以防止同时访问。

Case 2: You want each thread to do some sort of round robin processing where one thread runs, waits for 1 second and then updates the counter by its parameter amount. 情况2:您希望每个线程都执行某种循环处理,其中一个线程运行,等待1秒钟,然后按其参数数量更新计数器。 Then the next thread runs, wait for 1 second and updates the counter by its different parameter amount. 然后下一个线程运行,等待1秒钟,并通过其不同的参数量更新计数器。 And so on until you loop back to the first thread. 依此类推,直到您循环回到第一个线程。

This more case matches your example counter increment flow. 这种更多情况与您的示例计数器增量流匹配。 In this case condition variables could be used as long as the number of threads is 2 and you make sure to start them in a deterministic way. 在这种情况下,只要线程数为2,就可以使用条件变量,并确保以确定的方式启动它们。 With more then 2 threads then unless they are of different priority there is no guarantee of run order. 如果有2个以上的线程,那么除非它们的优先级不同,否则不能保证运行顺序。 Also starting them in a loop like that does not guarantee which will be executed first. 同样在这样的循环中启动它们并不能保证将首先执行。

In this case, only a single thread is working at a time while all other are waiting. 在这种情况下,一次只有一个线程在工作,而其他线程都在等待。 This is not a good candidate for a multithreaded solution. 对于多线程解决方案,这不是一个很好的选择。 A better patter would be a single thread and a work queue. 更好的模式是单线程和工作队列。 By this I mean create a circular queue of the various increment amounts desired and let a single thread run in a loop where it waits 1 second, pull reads the next increment amount from the queue and increments the counter, increments the queue pointer, and repeats. 我的意思是创建一个具有各种所需增量量的循环队列,并让一个线程在其中等待1秒钟的循环中运行,pull从队列中读取下一个增量量,并递增计数器,递增队列指针,然后重复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM