Witam
Chciałem napisać prosty demon TCP w C++, który służyłby mi jako prosty chat. W tym celu chciałem skorzystać z wielowątkowości biblioteki standardowej, lecz już w prostym przypadku natrafiam na problemy.
Moja koncepcja jest taka:
UserDispatcher : std::thread - klasa która będzie zarządzać połączeniami od nowych użytkowników.
User : std::thread - klasa obsługująca danego użytkownika
Na tę chwilę, celem uproszczenia, w wątku dispatchera nowy użytkownik tworzony jest co 2s, i każdy z nich wyświetla na standardowe wyjście w swoim imieniu swoje id. Poza tym nie dzieje się nic.
Teraz w przypadku gdy w funkcji run() dispatchera nowego użytkownika stworzę jawnie wołając "users.push_back(User(&mutex));" to program działa zgodnie z moim oczekiwaniem, natomiast zamknięcie tego fragmentu kodu w funkcję addUser() powoduje iż na standardowe wyjście zgłaszają się użytkownicy z id=0. Cóż robię nie tak?
Tzn. output w pierwszym przypadku:
New user
User thread entered, id: 0
New user
User thread entered, id: 1
New user
User thread entered, id: 2
W przypadku drugim:
New user
User thread entered, id: 0
New user
User thread entered, id: 0
New user
User thread entered, id: 0
Klasa UserDispatcher:
class UserDispatcher: public std::thread {
std::mutex mutex;
std::list<User> users;
void run(void);
void addUser(void);
public:
UserDispatcher(void);
};
void UserDispatcher::run(void) {
while(true) {
mutex.lock();
std::cout << "New user" << std::endl;
// users.push_back(User(&mutex)); //pierwszy przypadek
// addUser(); //drugi przypadek
mutex.unlock();
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
void UserDispatcher::addUser(void) {
users.push_back(User(&mutex));
}
UserDispatcher::UserDispatcher(void)
: std::thread(&UserDispatcher::run, this) {
}
Klasa User:
class User: public std::thread {
static int nextID;
std::mutex *mutex;
int id;
void run(void);
public:
User(std::mutex *mutex);
};
void User::run(void) {
mutex->lock();
std::cout << "User thread entered, id: " << id << std::endl;
mutex->unlock();
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
User::User(std::mutex *mutex)
: mutex(mutex), id(nextID++), std::thread(&User::run, this) {
}