Lipetsk *nix Association Forum Lipetsk *nix Association Forum
Новости:
 
*
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?
19 Апреля 2024, 23:36:25


Войти


Страниц: [1]   Вниз
  Печать  
Автор Тема: [c++]разнести класс на потоки  (Прочитано 16533 раз)
0 Пользователей и 1 Гость смотрят эту тему.
IERO
Модератор
*****

Карма: 8
Сообщений: 432


Debian Lenny


Награды
« : 02 Марта 2009, 19:16:05 »

нужно написать класс(или два), работающий с raw-сокетом(чтение и запись).
причем писать и читать надо независмо, т.е. не дожидаясь завершения записи чтобы начать оттуда читать. на си это реализовалось просто парой потоков работавших с одним сокетом. а тут нужно завернгуть все в класс.
в связи с этим вопрос - стоит ли вообще класс разносить на 2 потока или лучше сделать 2 класса и объект каждого пускать в своем потоке?
и если можно так делать - то лучше второй поток создавать в конструкторе, или отдельным методом?
Записан
Леголегс
Гуру
******

Карма: 18
Сообщений: 1006


Fedora 12 x86_64


Награды
« Ответ #1 : 02 Марта 2009, 20:21:08 »

Я бы начал примерно так:
Код:
class My_socket {
SOCKET socket;
Mutex mutex;
void write(...);
void read(...);
};
void My_socket::write(...)
{
mutex_wait(mutex);
int r = write(socket,...);
mutex_release(mutex);
if (! r)
throw("Нимагу писать фсокет!");
}
void My_socket::read(...)
{
mutex_wait(mutex);
int r = read(socket,...);
mutex_release(mutex);
if (! r)
throw("Нимагу фтыкать сокет!");
}
/*******************/
class My_thread {
My_socket * my_socket;
Thread thread;
My_thread(My_socket * new_my_socket):my_socket(new_my_socket),thread(0) {};
~My_thread() { if (thread) terminate(thread);};
void launch();
};

void My_thread::launch()
{
thread = create_thread(...);
if (!thread) throw("хрентам");
}
Записан

[ Мой FTP ftp://legolegs.homelinux.net ]
[ Репозиторий Fedora http://fedora.leschat.net/ ]
[ Репозиторий Ubuntu http://ubuntu.leschat.net/ ]
IERO
Модератор
*****

Карма: 8
Сообщений: 432


Debian Lenny


Награды
« Ответ #2 : 02 Марта 2009, 22:23:15 »

я не фрагмент кода спрашиваю, а концепцию.
и откройте секрет двоеточия необразованому человеку.
и коментов можно добавить Улыбка.
ничего не ясно в потоке чистого сознания.
Записан
IERO
Модератор
*****

Карма: 8
Сообщений: 432


Debian Lenny


Награды
« Ответ #3 : 02 Марта 2009, 22:43:53 »

Код:
class Pinger {
pthread_t thread;
Socket socket;
Cycle* cyclelist;
CycleResult * result;
Pinger();
Add(Cycle);
ExecCycle();
ReadSocket();
}

Pinger::Pinger()
{
socket=.....
thread =pthread_create(&secthread, ...);
.....
}

int secthread
{
while(1)
{
read(socket);
}
}
я имел ввиду нечто вроде этого.
и дальше основной поток может мучать Pinger как угодно ,а созданый внутри класса поток все работает и работает...
или это глупо и плохо?
Записан
Леголегс
Гуру
******

Карма: 18
Сообщений: 1006


Fedora 12 x86_64


Награды
« Ответ #4 : 02 Марта 2009, 23:33:12 »

Ну что-то вроде этого я и имел ввиду. Надо учесть ряд моментов:
1. возможно, захочется юзать в потоке членов класса. Это нормально и стесняться тут нечего Улыбка надо, само собой передать в secthread указатель на Pinger (типа pthread_create(&thread, NULL, secthread, this)).
2. Имей однако ввиду, что при 1. надо быть осторожным, трогая из основного потока содержимое Pinger. Сказав 'A', говори 'B'. Почти наверняка от синхронизации ты не отвертишься.
3. Естественно само собой разумеется надо в деструкторе мочить поток. Мочить можно по-плохому (man pthread_cancel) или по хорошему (послать так или иначе сообщение и ждать выхода с помощью pthread_join).
4. И если будешь юзать исключения, то try/catch должны быть в том же потоке, что и throw. Не знаю пока как в gcc, а в борландбилдере нарушение этого правила вызывало ужасные сообщения об ошибках.
Записан

[ Мой FTP ftp://legolegs.homelinux.net ]
[ Репозиторий Fedora http://fedora.leschat.net/ ]
[ Репозиторий Ubuntu http://ubuntu.leschat.net/ ]
IERO
Модератор
*****

Карма: 8
Сообщений: 432


Debian Lenny


Награды
« Ответ #5 : 02 Марта 2009, 23:48:54 »

1.можно второй поток сделать членом класса, к тому же приватным в моем случае.
спасибо за идею.
2. в момент когда сокету делают read, в него вполне можно вторым потоком делать write (по крайней мере с тцп/юдп такое катит). поэтому мьютексы в этом фрагменте вроде как лишние.
Записан
IERO
Модератор
*****

Карма: 8
Сообщений: 432


Debian Lenny

ОС:
Linux Linux
Браузер:
Opera 9.52 Opera 9.52


Награды
« Ответ #6 : 14 Мая 2009, 20:02:29 »

извиняюсь за некромантию, дубль 2. вопрос схожий, но поинтересней.

есть класс A, внутри которого существует список объектов класса B.
class A{
..........
list<B*> B_List;
...............
}
class B{
short m_die_status;
static void * FstThread(void *);
}
класс B имеет в конструкторе примерно такое:
B::B(....)
{
  if( ( pthread_create ( &main_thr, NULL, & (B::FstThread),this ) ) !=0)
    m_die_status=1;
}
в деструкторе
B::~B(....)
{
    m_die_status=1;
  pthread_join (main_thr, NULL );
}
при этом осознание что пора заканчиваться наступает в потоке который FstThread.
возникает вопрос - каким образом своевремено чистить B_List от тех объектов потоки которых уже отработали?
или данная концепция изначально порочна и лучше в классе A создавать нитки, и внутри ниток создавать уже объекты, и как можно отслеживать в таком случае?
Записан
Леголегс
Гуру
******

Карма: 18
Сообщений: 1006


Fedora 12 x86_64

ОС:
Linux Linux
Браузер:
Opera 9.63 Opera 9.63


Награды
« Ответ #7 : 14 Мая 2009, 20:16:44 »

У тебя m_die_status что означает? "насяльника, я не смог стартовать, добей меня" или "щас сдохну, сдохну, сдохну, честноеслово, щас ещё чуть чуть и сдохну..." Ты определись, да.
И ещё. разве твои потоки могут дохнуть сами? вроде они должны работать пока их не прибьют.
А вообще, ведёщие собаководы вроде как передают в таких случаях ссылку на контейнер в экземпляры.
Записан

[ Мой FTP ftp://legolegs.homelinux.net ]
[ Репозиторий Fedora http://fedora.leschat.net/ ]
[ Репозиторий Ubuntu http://ubuntu.leschat.net/ ]
IERO
Модератор
*****

Карма: 8
Сообщений: 432


Debian Lenny

ОС:
Windows XP Windows XP
Браузер:
MS Internet Explorer 6.0 MS Internet Explorer 6.0


Награды
« Ответ #8 : 14 Мая 2009, 22:23:40 »

m_die_status по моим арсчетам может работать в 2 стороны. по его значению понимается успешность вызова конструктора объекта(проверяется значение после создания), и по нему же помирает второй поток.

про ссылку на контейнер это как?
передавать указатель на лист, и в деструкторе приказывать мочить элемент в листе?

упд: маскировка работает Улыбка
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2011, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM