URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9432
[ Назад ]

Исходное сообщение
"pthread_create + полиморфизм = проблема с передачей 4 аргумента"

Отправлено anselm , 12-Апр-12 14:06 
Добрый день, друзья.
При написании многопоточного сервера столкнулся со странной проблемой.
Попробую как могу описать суть.
Вначале всё работало и выглядело примерно так:

bool TCP_parent::listen() {
  int new_socket = ::accept(...);
  pthread_create(&thread1, NULL, start_routine, (void*) &socket);
}

Потом я переместил вызов функции pthread_create в дочерний класс, точнее переопределил родительский метод TCP_parent::accept:

bool TCP_parent::listen() {
  int new_socket = ::accept(...);
  accept(new_socket);
}

bool TCP_child::accept(int sock) {
  pthread_create(&thread1, NULL, start_routine, (void*) &sock);
}

После этой безобидной операции функция потока start_routine перестала получать свой аргумент sock. Точнее после разыменования аргумента *((int*)ptr) получалось что-то неудобочитаемое, типа 134515204. Может в g++ не работает как надо полиморфизм?

# uname -a
FreeBSD srv-prog2.ru 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010     root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

# g++ --version
g++ (GCC) 4.2.1 20070719  [FreeBSD]
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Содержание

Сообщения в этом обсуждении
"pthread_create + полиморфизм = проблема с передачей 4 аргумента"
Отправлено anselm , 12-Апр-12 14:45 
Всем спасибо, причину нашёл.
Неверно определил аргумент:

-bool TCP_child::accept(int sock)

+bool TCP_child::accept(const int& sock)


"pthread_create + полиморфизм = проблема с передачей 4 аргумента"
Отправлено elvenic , 12-Апр-12 18:30 
> bool TCP_parent::listen() {
>   int new_socket = ::accept(...);
>   pthread_create(&thread1, NULL, start_routine, (void*) &socket);
> }

Вы, конечно, понимаете, да,  что передаете в функцию которая запускается во втором thread'e адрес локальной переменной которая размещеня в стеке перого thread'a? (В смысле, что нет никакой гарантии что в тот момент когда start_routine() во втором thread'е попытается прочитать значение типа int по этому адресу, TCP_parent::listen() в первом thread'е уже может завершится и ее локальнй переменной new_socket (адрес которой и был передан) может не существовать?)


"pthread_create + полиморфизм = проблема с передачей 4 аргумента"
Отправлено anselm , 13-Апр-12 06:53 
>> bool TCP_parent::listen() {
>>   int new_socket = ::accept(...);
>>   pthread_create(&thread1, NULL, start_routine, (void*) &socket);
>> }
> Вы, конечно, понимаете, да,  что передаете в функцию которая запускается во
> втором thread'e адрес локальной переменной которая размещеня в стеке перого thread'a?
> (В смысле, что нет никакой гарантии что в тот момент когда
> start_routine() во втором thread'е попытается прочитать значение типа int по этому
> адресу, TCP_parent::listen() в первом thread'е уже может завершится и ее локальнй
> переменной new_socket (адрес которой и был передан) может не существовать?)

Это я упустил. Получается, надо создать динамическую переменную:

bool TCP_parent::listen() {
  int* new_socket = new int( ::accept(...) );
  pthread_create(&thread1, NULL, start_routine, (void*) new_socket);
}

- а функция start_routine должна взять на себя уничтожение этой переменной.

Да, всё заработало. Вы ответили на мой вопрос. Большое спасибо!