Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
diplomat1129
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 83
#1

Поток из не статического метода - C++

12.04.2014, 12:22. Просмотров 290. Ответов 6
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
            try{
                    _Running = true;
 
                    iret = pthread_create(&_ThreadRunClient, NULL, Run_Client, 0);
                    //pthread_join(_ThreadRunClient, NULL);
 
                }catch (exception& e){
Run_Client() - статичный метод, получилось так, что его надо сделать не статичным. Из-за этого создание потока выдает ошибку
NMClient.cpp: In member function ‘void NMClient::RunClient()’:
NMClient.cpp:212:81: error: cannot convert ‘NMClient::Run_Client’ from type ‘void* (NMClient:(void*)’ to type ‘void* (*)(void*)’
iret = pthread_create(&_ThreadRunClient, NULL, Run_Client, 0);
^
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.04.2014, 12:22     Поток из не статического метода
Посмотрите здесь:

Инициализация статического массива C++
Можно ли создать поток для нестатического метода класса? C++
Классы: как из статического метода обратиться к статической переменной класса C++
Размер статического массива C++
Объявление статического объекта C++
C++ Из статического массива в динамический
из статического в диномический массив C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Voivoid
 Аватар для Voivoid
593 / 269 / 12
Регистрация: 31.03.2013
Сообщений: 1,328
12.04.2014, 12:24     Поток из не статического метода #2
Очевидно, что pthreads не нужны, используй std::thread или boost::thread
0x10
2442 / 1614 / 235
Регистрация: 24.11.2012
Сообщений: 3,962
12.04.2014, 12:26     Поток из не статического метода #3
Если нельзя отказаться от pthreads, пишешь новый static метод, куда первым аргументом передаешь this, от которого уже вызываешь нестатичный метод.
diplomat1129
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 83
12.04.2014, 13:57  [ТС]     Поток из не статического метода #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        //Запуск клиента
    void RunClient(){
 
        int iret;
 
        if (!Running){
            try{
                    _Running = true;
 
                    iret = pthread_create(&_ThreadRunClient, NULL, Run_Client, 0);
                    //pthread_join(_ThreadRunClient, NULL);
 
                }catch (exception& e){
                    _Running = false;
                    throw std::invalid_argument("Невозможно запустить клиент");
                }
        }
        else{
            throw std::invalid_argument("Клиент уже остановлен");
        }
    }
Добавлено через 1 час 4 минуты
Этот метод сделать статичным? он и есть как обертка над созданием потока.
0x10
2442 / 1614 / 235
Регистрация: 24.11.2012
Сообщений: 3,962
12.04.2014, 14:24     Поток из не статического метода #5
Блин, кидаете куски кода, которые по сути к делу отношения имеют мало.
Ну попытаюсь восстановить.

Предполагаю, что исходно было так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
#include <pthread.h>
 
struct Client
{
    static void* StartRoutine(void*)
    {
        std::cout << "Client::StartRoutine" << std::endl;
        return NULL;
    }
};
 
int main()
{
    pthread_t thread;
    pthread_create(&thread, NULL, Client::StartRoutine, NULL);
 
    pthread_join(thread, NULL);
    std::cout << "Joined" << std::endl;
}
Внезапно StartRoutene перестал быть статичным методом.
Вопрос: где в последнем коде объект, для которого будет вызваться этот метод в потоке?

Естественно, с сишной точки зрения сигнатура нестатичного метода отличается от статичного - первым аргуметом неявно передается указатель на объект, для которого вызывается метод. Т.е. если в моем примере StartRoutine сделать нестатичным, то он будет эквивалентен чему-то вроде
C++
1
void* _Client_StartRoutine(Cliient* const this, void*)
Очевидно, сигнатура отличается от той, что требует функция pthread_create. Поэтому я и говорю, что нужно сделать дополнительный статичный метод, которому в качестве аргумента можно будет явно передать this.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
 
#include <pthread.h>
 
struct Client
{
    void* StartRoutine(void*)
    {
        std::cout << "Client::StartRoutine" << std::endl;
        return NULL;
    }
 
    static void* StartRoutineHelper(void* arg)
    {
        Client* const obj = reinterpret_cast<Client* const>(arg);
        return obj->StartRoutine(NULL);
    }
};
 
int main()
{
    Client client;
    pthread_t thread;
    pthread_create(&thread, NULL, Client::StartRoutineHelper, &client);
 
    pthread_join(thread, NULL);
    std::cout << "Joined" << std::endl;
}
DrOffset
6817 / 4028 / 924
Регистрация: 30.01.2014
Сообщений: 6,847
12.04.2014, 14:36     Поток из не статического метода #6
diplomat1129,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class MyThread
{
public:
    void run()
    {
        if(!running_)
        {
            // pthread не бросает никаких исключений
            running_ = pthread_create(&thread_, NULL, &MyThread::pthread_func_impl, this) != 0;
            if(!running_)
            {
                throw std::invalid_argument("Невозможно запустить клиент");
            }
        }
        else
        {
            throw std::invalid_argument("Клиент уже остановлен");
        }
    }
 
    void thread_func()
    {
        // здесь пишем код
    }
 
private:
    static void * pthread_func_impl(void * data)
    {
        try
        {
            if(MyThread * this_ = static_cast<MyThread *>(data))
            {
                this_->thread_func();
            }
        }
        catch(...)
        {
            // здесь какая-то обработка
            // нельзя выпускать исключения за пределы потока
        }
        return NULL;
    }
 
    pthread_t thread_;
    bool      running_;
};
Добавлено через 2 минуты
0x10,
Что-то я долго свой пост писал.
Цитата Сообщение от 0x10 Посмотреть сообщение
C++
1
Client* const obj = reinterpret_cast<Client* const>(arg);
Только вот здесь кошернее static_cast применять
0x10
12.04.2014, 14:38     Поток из не статического метода
  #7

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Только вот здесь кошернее static_cast применять
Ну я чет перестарался.

Yandex
Объявления
12.04.2014, 14:38     Поток из не статического метода
Ответ Создать тему
Опции темы

Текущее время: 00:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru