vendredi 24 juillet 2020

First steps with threading failed

Hi: please further down find my code. I compiled using mingw with parameters -Wmain;-pedantic;-std=c++11;-Wall. Codelite set the semicola between the compiler options

Here I tried to learn how to use thread and mutex: https://en.cppreference.com/w/cpp/thread/mutex

The main module contains the global variable std::mutex mtx after the include section The thread functions are declared and joined in the main() function; the function definitions for friend class SL can be found here as well. Class and method definitions are spread over the next to modules.

These are the error messages, which I cannot handle: Message 1 C:/Program Files/CodeBlocks/MinGW/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/thread:240:2: error: no matching function for call to 'std::thread::_Invoker<std::tuple<void ()(int, int, SL&), int, int, SL> >::_M_invoke(std::thread::_Invoker<std::tuple<void ()(int, int, SL&), int, int, SL> >::_Indices)' operator()() ^~~~~~~~ Message 2 C:/Program Files/CodeBlocks/MinGW/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/thread:233:29: error: no matching function for call to '__invoke(std::__tuple_element_t<0, std::tuple<void ()(int, int, SL&), int, int, SL> >, std::__tuple_element_t<1, std::tuple<void ()(int, int, SL&), int, int, SL> >, std::__tuple_element_t<2, std::tuple<void ()(int, int, SL&), int, int, SL> >, std::__tuple_element_t<3, std::tuple<void ()(int, int, SL&), int, int, SL> >)' -> decltype(std::__invoke(_S_declval<_Ind>()...)) __invoke(_Callable&& __fn, _Args&&... __args) ^~~~~~~~

*Message 2 seems to make reference to some type of move constructor ...

I had the idea that the friend function is cause of the dilemma, but was not able to verify

Please help with this.

main module

#include <mutex>
#include <thread>
#include "sl.h"
std::mutex mtx;

void play(int die1, int die2, SL& p){
  std::this_thread::sleep_for(std::chrono::seconds(1));
  mtx.lock();
  if (p.dice.size() > 0) {
    p.dice.resize(0);
    }
  p.set_dice(die1, die2);
  rollDice(p);
  mtx.unlock();
  }

void rollDice(SL& p) {
  int iFound = -1;
  int iAdd = p.dice[0] + p.dice[1];
  p.addPosition(iAdd);
  p.bounceBack();
  if (p.position == 100) {
    printResult(p, iFound);
    std::cout << "Game over" << std::endl;
    return;
    }
  if ((iFound = p.check(SL::ladders, p.position)) != -1) {
      p.setPosition(SL::ladders[iFound].second);
      iFound += 100;
      }
  else if ((iFound = p.check(SL::snakes, p.position)) != -1) {
      p.setPosition(SL::snakes[iFound].second);
      }// snakes, position + iAdd
  printResult(p, iFound);
  if (p.dice[0] == p.dice[1]) {
    mtx.unlock();
    play(rand() %6 + 1, rand() % 6 + 1, p);
    }
  }

void printResult(SL& p, int iFound) {
  std::cout << ++p.iTimes << ") "
            << p.get_name() << "<<<< "
            << p.dice[0] << "|"
            << p.dice[1] << " position: "
            << p.position;

  if (iFound != -1) {
    if (iFound > 100) { // this is a ladder field
      iFound -= 100;
      std::cout << " LADDER from "
                << SL::ladders[iFound].first << "|"
                << SL::ladders[iFound].second;
        }
    else {
      std::cout << " SNAKE from "
                << SL::snakes[iFound].first  << "|"
                << SL::snakes[iFound].second;
        }
      }
    std::cout << std::endl;
    }

int main()
  {
  srand(time(NULL));
  SL one("Player 1"),
                two("Player 2");
  std::thread t1 (play, rand() %6 + 1, rand() %6 + 1, one);
  std::thread t2 (play, rand() %6 + 1, rand() %6 + 1, two);
  while((one.get_position() != 100) && (two.get_position() != 100)) {
    t1.join();

    t2.join();
    }
  return 0;
  }

// Class Declaration

#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <ctime>
#include <iomanip>

class SL {
  public:
  SL(const std::string& strName) : player(strName), position(0), iTimes(0) {}
  ~SL() = default;

  private:
    friend void play(int die1, int die2, SL& p);
    friend void rollDice(SL&);
    friend void printResult(SL&, int);
    static const std::pair<int, int> snakes[];
    static const std::pair<int, int> ladders[];
    std::string player;
    int position;
    int iTimes;
    std::vector<int> dice;
  protected:
    int check(const std::pair<int, int> field[], const int iField);
  public:
    void addPosition(const int iPosition);
    void setPosition(const int iPosition);
    void bounceBack();
    void set_dice(int die1, int die2);
    const int get_position() const;
    const std::string& get_name() const;
    const std::vector<int> get_dice() const;
    };
// friend function
void play(int die1, int die2, SL& p);
void rollDice(SL&);
void printResult(SL&, int =-1);

// Class methods - static variables

#include <mutex>
#include <thread>
#include "sl.h"

inline void SL::addPosition(const int iPosition) {
  position += iPosition;
  }
inline void SL::setPosition(const int iPosition) {
  position = iPosition;
  }
inline void SL::bounceBack() {
  if (position > 100) {
    int iBounceBack = position - 100;
    position -= iBounceBack;
    }
  }
inline void SL::set_dice(int die1, int die2){
  if (dice.size() > 0) {
    dice.erase(dice.begin(), dice.end());
    }
  dice.push_back(die1);
  dice.push_back(die2);
  }
const int SL::get_position() const {return position;}
const std::string& SL::get_name() const {return player;}
const std::vector<int> SL::get_dice() const {return dice;}

int SL::check(const std::pair<int, int> field[], const int iField) {
  const int end = 10;
  int result = -1;
  for ( size_t idx = 0; idx < end; idx++) {
    if (field[idx].first == iField){
      result = idx;
      break;
      }
    else if (iField > field[idx].first)
      break;
    }
  return result;
}

const std::pair<int, int> SL::ladders[] {
      std::make_pair( 2, 38),
      std::make_pair( 7, 14),
      std::make_pair( 8, 31),
      std::make_pair(15, 26),
      std::make_pair(28, 84),
      std::make_pair(36, 44),
      std::make_pair(51, 67),
      std::make_pair(71, 91),
      std::make_pair(78, 98),
      std::make_pair(87, 94)
      };

const std::pair<int, int> SL::snakes[] {
      std::make_pair(16,  6),
      std::make_pair(46, 25),
      std::make_pair(49, 11),
      std::make_pair(62, 19),
      std::make_pair(64, 60),
      std::make_pair(74, 53),
      std::make_pair(89, 68),
      std::make_pair(92, 88),
      std::make_pair(95, 75),
      std::make_pair(99, 80)
      };

Aucun commentaire:

Enregistrer un commentaire