Как можно создать поток с указанием на функцию которая является элементом класса. Т.е. когда я делаю так:
class A:
{
...
void Init(void *arg);
...
};
A::A()
{
pthread_attr_t tattr;
pthread_t tid;
extern void *Init(void *arg);
void *arg;
int ret;
ret = pthread_create(&tid, NULL, Init, arg);
ret = pthread_attr_init(&tattr);
ret = pthread_create(&tid, &tattr, Init, arg);
}
void A::Init(void *arg)
{
...
}
то в итоге получаю сообщение о том что имеется необъявленная ссылка на Init.
И сюда же вопрос, можно ли в такую функцию передать что либо отличное от void *arg, типа char *a,int b...
Заранее спасибо!!!
> А можно пояснить сокральный смысл вызова вот этой функции?!
> ::pthread_join(t.id(), 0);
основной поток породил дочерний и ему как-то нужно дождаться его
завершения перед тем, как завершить процесс. pthread_join() делает
то самое aka завершения потока с указанным идентификатором.
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_join.html
> и два двоеточия в начале это опечатка или то же имеет смысл?
ну почему же опечатка, это явное указание на то, что функция
pthread_join() равно как и pthread_create() находятся в глобальном
пространстве имен бо в общем случае они могут быть перекрыты методами
класса, using namespace или еще какой херней. например:
--- cut ---
#include <iostream>
void
fnc()
{
std::cout << "Global fnc" << std::endl;
}
class foo {
public :
void fnc() {
std::cout << "Class fnc" << std::endl;
}
void test() {
fnc();
::fnc();
}
};
int
main(int argc, char *argv[])
{
foo f;
f.test();
return 0;
}
--- cut ---
foo@ip-230$ g++ -Wall -o foo foo.cc
Press any key to continue...
foo@ip-230$ ./foo
Class fnc
Global fnc
называется "почувствуй разницу". как следствие, если вы явным образом
обращаетесь к функции из глобального пространства имен, это лучше
всего не забывать указывать через пустое имя "::". иначе могут быть
проблемы.
// wbr
ну возьмите да засуньте, в чем проблемы? никто не запрещает. только все-таки в base_thread а не my_thread бо последний нужен лишь для того, чтобы реализовать метод абстрактный run(). ну например:
--- cut ---
class base_thread {
public :
virtual ~base_thread() {}
// Must be implemented by real client
virtual void *run() = 0;
int start() {
return ::pthread_create(&pth_, 0, real_run, this);
}
void wait() {
::pthread_join(pth_, 0);
}
private :
pthread_t pth_;
static void * real_run(void *arg) {
base_thread *t = static_cast<base_thread *>(arg);
return t->run();
}
};
--- cut ---
// wbr
"не прокатывало" - это значит не компилируется чтоль ? =)
повторю предыдущего оратора, pthread_join _усыпляет вызывающий_ поток до тех пор пока не завершится указанный (pth_)
то есть Вы создали дочерний поток и потом усыпили основной, до тех пор, пока не завершится дочерний. оригинально :) зачем тогда второй поток Вам вообще нужен ? :)
ps: кстати - не вздумайте засунуть start() в этом виде в конструктор :)