2016-04-25 2 views
0

Я работаю на сервере, который имеет вектор потоков, как это:Стирание нити внутри функции она делает

vector<thread> thred; 

И каждый раз, когда клиент подключается к серверу, он создает новый поток в сервер, например:

thred.push_back(thread(NewClient, ClientSocket, recvbuf, recvbuflen)); 
thred[thred.size()-1].detach(); 

Где NewClient функция с аргументами ClientSocket, recvbuf и recvbuflen. Поэтому мой вопрос заключается в том, есть ли какой-либо способ или функция, которую я могу использовать внутри NewClient, чтобы закрыть поток и удалить элемент вектора, который использует сам fuction.

Любая помощь будет оценена по достоинству.

+1

Одна из проблем, о которых я могу думать, чтобы синхронизировать это, чтобы вы не получали никаких гонок данных, вам понадобится блокировка мьютекса, но если вы удалите блокирующий поток, пока он все еще заблокирован, вы у вас больше нет нити, чтобы разблокировать ресурс. Который бы навсегда заблокировал вашу программу. – Stephen

+0

@ simpel01 прямо сейчас это то, что делает программа, вектор растет для каждого соединения, и моя цель состоит в том, чтобы иметь только элемент для каждого соединения, которое есть в данный момент, поэтому когда NewClient заканчивается, я хотел бы удалить поток и элемент вектора? там в любом случае? – 19mike95

+0

@Stephen да, это будущая проблема, но в настоящее время у нас нет мьютекса, поэтому я задаюсь вопросом, есть ли что-то, чтобы закрыть поток, стереть вектор и разблокировать мьютекс (внутри функции NewClient, i – 19mike95

ответ

0

Возможно использование map<int,thread> вместо vector для хранения ваших потоков и передачи ключа карты потока в качестве дополнительного параметра для метода потока. Когда поток выполняется, он может удалиться из главной таблицы.

Ключ карты может быть чем-то простым, как постоянно увеличивающееся целочисленное значение.

Не забудьте обернуть стол мьютексом или чем-то подобным, как сказал Стефан.

+0

Я вижу, что вы говорите о карте с ключевым параметром (чтобы узнать, какой поток удалить?), Но я не понимаю, как я могу закрыть мьютекс. – 19mike95

+0

Да, ключ карты передается в поток, поэтому поток может стереть свою собственную запись на карте ('map.remove'). «Обернуть таблицу с помощью мьютекса» означает «блокировать()» мьютекс, прежде чем обращаться к нему, а затем «разблокировать()» после. Объявите мьютекс в той же области, что и массив потоков (не внутри самого потока). Проверьте http://en.cppreference.com/w/cpp/thread/mutex –

0

Может создать еще один вектор

vector<int> thread_exit_time; 

и установите его на время Sytem, ​​когда функция нить NewClient выходов. Вместо того, чтобы звонить thred.push_back, вы можете проверить thread_exit_time и заменить те мертвые потоки.

С тех пор как вы звоните detach, нет другого способа проверить, существует ли нить от нет.

Это может быть лучше, создающих вектор pair

vector<std::pair<thread,int>> thread; 

, чтобы убедиться, что оба вектора синхронизируются.

В любом случае, вы должны сначала подумать о том, почему вам нужно вести список отдельных тем, что и @SergeyA.