LINUX.ORG.RU

С++:Метод как функция потока


0

0

Здравствуйте! Подскажите плиз, можно ли pthread_create() передать указатель на метод в качестве функции потока? Насколько я понял, нельзя из-за *this, но ведь делают же как-то :((. И каким метод должен быть - приватным/публичным? Статическим нельзя из-за специфики класса. Заранее спасибо.

Ответ на: комментарий от cvv

Да, точно нужны, весь класс проверяет наличие inotify в glibc, в случае удачи запускает поток получения событий. И есть публичные методы start/stop, которые должны этот поток запускать/останавливать. Соответственно, нужно сделать функцией потока приватный метод run (обойти через внешнюю функцию или статический метод нельзя, потому что нужен доступ к приватным методам и старт/стоп должен быть для каждого экземпляра класса свой). PS:Спасибо, второй раз уже помогаете! :)

flagist0
() автор топика

> Статическим нельзя из-за специфики класса. Заранее спасибо.

Существуют по большому только 2 способа: статический метод и friend функция класса. Конечно попробовать можно передавать указательно на метод класса без аргументов, закастив его 10 раз, т.к. первый аргумент всегда подразумевается this, но мне кажется, это не самый лучший способ.

fmj
()
Ответ на: комментарий от fmj

За friend-функцию большое спасибо. Щаз попробую.

flagist0
() автор топика

boost::bind (+ посмотрите boost::thread)

Deleted
()

class MyClass {
public:
    void run() {
    }

    static void* runWrapper(void* thisPtr) {
        ((MyClass*) thisPtr)->run();
        return null;
    }
}

<...>

MyClass* obj = new MyClass();
pthread_create(..., &MyClass::runWrapper, obj);

как то так.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Только про mutex для защиты от неатомарных операция изменения класса не забудьте...

krum
()
Ответ на: комментарий от Legioner

Лучше friend.

static использовать некошерно, у него сигнатура вызова теоретически может не совпадать с ожидаемым для pthread_create() extern "C".

execve
()
Ответ на: комментарий от Legioner

Теоретически такое работать не должно и скорее всего будут топтания по памяти...

>&MyClass::runWrapper

насколько я понимаю эта штука имеет размер более 4 байт а pthread_create ждет именно 4.

да и с аргументами там не всё благополучно...

cvv ★★★★★
()
Ответ на: комментарий от flagist0

А как на тему неблокирующего поллинга?

cvv ★★★★★
()
Ответ на: комментарий от cvv

Возможно по стандарту это не гарантируется, но какие могут быть разумные причины компилятору делать статические методы отличными от обычных функций?

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

насколько я понимаю дело в том что это полностью оставлено на усмотрение разработчиков компилера и ничем не регламентируется - следственно компилер вправе генерить совершенно несовместимый код например просто при изменении уровня оптимизации

cvv ★★★★★
()

посмотри как сделано в boost::thread

acefsm
()
Ответ на: комментарий от cvv

>насколько я понимаю эта штука имеет размер более 4 байт

ага 5 байт. Кто вам такое сказал? И что там с аргументами?

Vinick ★★
()
Ответ на: комментарий от cvv

> Где ты видиш указатель? это не С. амперсанд в плюсах может возвращать вообще что угодно

Страуструп пишет что статический член не ассоциируется с конкретным объектом, так что указатель на статический член похож на обыкновенный указатель.

И приводит пример: class Task { static void schedule(); }; void (*p)() = &Task::schedule;

так что указатель на статический член должен быть имхо эквивалентен указателю на обычную функцию.

Eshkin_kot ★★
()
Ответ на: комментарий от cvv

>амперсанд в плюсах может возвращать вообще что угодно

Не что угодно, а только то то, что написано. Можно пример переопределения амперсанда для рассматриваемого случая. У меня не получилось. gcc хочет либо класс, либо перечислимый тип.

И даже если это так. то pthread_create хочет именно указатель на функцию ,причем функцию определенной сигнатуры, и засунуть туда что-то иное так просто не получится. Это не динамическая типизация.

Vinick ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.