Форум программистов, компьютерный форум, киберфорум
Кроссплатфор­менная разработка
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.84/55: Рейтинг темы: голосов - 55, средняя оценка - 4.84
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298

wxWidgets + многопоточность = ошибка сегментирования

08.08.2023, 08:16. Показов 13646. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.

Имеем:
1. wxWidgets 3.2.2;
2. windows 10 x64;
3. debian 11.5 (virtualBox);
4. многопоточность (std );
5. socket tcp\ip.

Что не так:
1. В виндовс работает на линуксе нет;
2. В линуксе при запуске через терминал выдает ошибку "ошибка сегментирования"

Описание:
Что делал см. ниже.
Кликните здесь для просмотра всего текста

Изначально прогу писал на винде, все запускалось, потом этот же код перенес на линукс и при запуске стал получать ошибки, некоторые устранил, но одну(если она одна) устранить на данный момент не понимаю как. Дело касается многопоточности.
В программе использую потоки из пространства имен std а не виджетовский класс. Прочитав мануал, было сказано делать многопоточность так, что бы графику обновлял\занимался основной поток. Как мне кажется(хотя есть вопросы). я так и сделал.
Запускаю прогу через терминал и вижу сообщение об ошибке сегментирования, убил весь вечер пересматривая циклы с массивами и векторами. Вполне возможно пропустил. Но вроде все ок.


Что делал:
1. Весь вечер пересматривал циклы с массивами и векторами. Вроде все ок;
2. В конструкторе в самом конце создал цикл, в котором создаются события нажатия на кнопку "присоединиться", далее после обработки этого события вызывается метод, в котором создается соединение, включаются\отключаются кнопки и устанавливается текст:
Говнокод этого метода:
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
void Class::makeConnection (int aI) {
 
    m_darrayDisconnectButton [aI] ->Enable (true);
 
    this->changeStatusConnect (aI);
 
    #ifdef windows1
        SOCKET socket1 = socket (AF_INET, SOCK_STREAM, 0);
        m_arraySocket [aI] = socket1;
    #endif // windows1
 
    #ifdef linux1
        int socket1 = socket (AF_INET, SOCK_STREAM, 0);
        m_arraySocket [aI] = socket1;
    #endif // linux1
 
    std::string stringIp = (m_darrayTextCtrlIp [aI] ->GetLineText (0)).ToStdString();
    std::string stringPort = (m_darrayTextCtrlPort [aI] ->GetLineText(0)).ToStdString();
 
    sockaddr_in addr1;
    addr1.sin_family = AF_INET;
    addr1.sin_addr.s_addr = inet_addr (stringIp.c_str());
    int intPort = stoi (stringPort);
    addr1.sin_port = htons (intPort);
 
    wxString wxStringResult (wxEmptyString);
    wxString wxStringResultPart1 (wxT ("111"));
    int attempt = 1;
    int codeCheck = 0;
 
    while (attempt < 4) {
        wxString wxStringAttempt = wxString::Format (wxT ("%i"), attempt);
        wxString wxStringResultPart2 (wxT ("/3"));
        wxStringResult = wxStringResultPart1 + wxStringAttempt
                                    + wxStringResultPart2;
 
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxStringResult);
        wxStringResult.clear();
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
 
        codeCheck = connect (m_arraySocket [aI], (sockaddr*)&addr1, sizeof (addr1));
 
        ++attempt;
 
        if (codeCheck == 0) {
            break;
        }
 
        if ( ! m_darrayDisconnectButton [aI] ->IsEnabled()) {
            codeCheck == -1;
            break;
        }
    } // while (attempt).
 
    if (codeCheck != 0) {
        #ifdef windows1
            closesocket (m_arraySocket [aI]);
        #endif // windows1
 
        #ifdef linux1
            close (m_arraySocket [aI]);
        #endif // linux1
 
        this->markTime (wxT ("111"), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
 
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxT ("111"));
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
        m_darrayConnectButton [aI] ->Enable (true);
        m_darrayDisconnectButton [aI] ->Enable (false);
 
        if (m_numberOfConnection == 0) {
            m_disconnectAllButton ->Enable (false);
            m_connectAllButton->Enable (true);
        }
        else if ( (m_numberOfConnection > 0)
                    | (m_numberOfConnection < m_numberOfMoxa) ) {
            m_disconnectAllButton ->Enable (true);
            m_connectAllButton->Enable (true);
        }
        else if (m_numberOfConnection == m_numberOfMoxa) {
            m_disconnectAllButton ->Enable (true);
            m_connectAllButton->Enable (false);
        }
    }
    else if (codeCheck == 0) {
        m_arraySendingError [aI] = false;
        m_arrayReceived [aI] = false;
        m_arrayReconnect [aI] = false;
 
        m_mutex1.lock();
            ++m_numberOfConnection;
        m_mutex1.unlock();
 
        m_arrayStatusStop [aI] = true;
        m_arrayStatusPause [aI] = false;
 
        if (m_darrayCheckBoxGeneralParameters [aI] ->IsChecked() ) {
            this->copyGenerallSettings (aI);
        }
 
        wxString wxStringPart1 (wxT ("111"));
        this->markTime ( (*m_darrayNameEquipments [aI] + wxStringPart1), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
 
        this->switchOnAcDc (aI);
        this->markTime (wxT ("111"), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxT ("111"));
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
        m_Graph->setColorGraph (aI, *m_darrayWxColor
                                                        [
                                    m_darrayChoiceColour [aI] ->GetSelection ()
                                                        ]);
 
        std::thread t1 (&Ses21::sendPackage, this, aI);
        t1.detach ();
 
        m_Graph->setCurrentGraph (aI);
 
        wxCommandEvent event1 (wxEVT_RADIOBUTTON,
                                        (m_darrayRadioButton [6])->GetId() );
        event1.SetEventObject (this);
        ProcessWindowEvent (event1);
 
        this->markTime (wxT ("111"), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxT ("111"));
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
 
        this->markSettings (aI);
 
        this->enableParameters (true);
        this->enableParameters (true, aI);
 
        wxCommandEvent event2 (wxEVT_CHECKBOX,
                                    (m_darrayCheckBoxGeneralParameters [aI])->GetId() );
        event2.SetEventObject (this);
        ProcessWindowEvent (event2);
 
        this->enableButtons (m_buttonChange->GetId(), true);
        this->enableButtons (m_buttonStop->GetId(), true);
        this->enableButtons (m_buttonPause->GetId(), true);
        this->enableButtons (m_buttonStart->GetId(), true);
 
        this->enableButtons ( (m_darrayPingButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayStartButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayChangeButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayStopButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayPauseButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayDisconnectButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayConnectButton [aI])->GetId(), false);
 
        this->enableButtons (m_disconnectAllButton->GetId(), true);
        }
    }
}
3. Если закомментировать все строки у "else if (codeCheck == 0)" то прога запускается;
4. Если раскомментировать в "else if (codeCheck == 0)" 3 строки, в которых происходит установка значений в массиве, а остальные не раскомментировать, то прога стабильно не запускается и пишет "ошибка сегментирования". Видимо я неправильно понял как использовать многопоточность...

Вопросы:
1. Где я допустил ошибку(а если она в этом методе, то и в других) ?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.08.2023, 08:16
Ответы с готовыми решениями:

wxWidgets: 2 х wxTextCtrl = ошибка завершения программы
Здравствуйте. Имеем: Простой код с двумя объектами wxTextCtrl. Что не работает: При закрытии программы, закрывается с...

Странная ошибка компиляции проекта Code::Blocks, wxWidgets
Здравствуйте. Встретился с багом, над выявлением которого работал опытным путём весь день. Работаю в Code::Blocks 20.03, wxSmith -...

Почему ошибка сегментирования (многопоточность)
Здравствуйте, проблема следующая: когда я пытаюсь разделить график и логику приложения в разные потоки, оно работает нормально, но при...

6
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
12.08.2023, 12:03
Лучший ответ Сообщение было отмечено Palich как решение

Решение

Palich, с многопоточностью (если конечно действительно в ней дело, а то не факт) чтобы найти ошибку нужно видеть весь контекст использования разделяемых ресурсов, а его вы не предоставили. Вот почему, например, нет метода sendPackage? Он ведь явно что-то делает с данными, которые вы подготовили в проблемной ветке условия.

В этом коде я пока вижу только ошибку дизайна. У вас и GUI и низкоуровневая работа с сетью и какая-то логика - все в одном методе. Это очень плохо и поэтому вам так сложно программировать и находить ошибки.
По-хорошему работа с сетью - это должен быть отдельный класс, который вы отдельно оттестируете, определите для него публичные контракты и в соответствии с ними будете его использовать в какой-то логике. Сама же логика должна быть отделена от GUI: сможете написать так, чтобы вашу логику можно было в другую GUI-подсистему сунуть, считайте что цель достигнута. А все это к чему? К простоте. Чем меньше зависимостей между компонентами программы, тем проще их тестировать и исправлять в них ошибки.
0
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 866
13.08.2023, 19:45
Цитата Сообщение от Palich Посмотреть сообщение
В линуксе при запуске через терминал выдает ошибку "ошибка сегментирования"
что мешает запустить в отладчике в линуксе? и посмотреть где беда
0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
23.08.2023, 10:04  [ТС]
спасибо за ответы, пока не могу вернуться к этой проблеме. Как вернусь, напишу что сделал и что получилось.
0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
21.09.2023, 23:37  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
В этом коде я пока вижу только ошибку дизайна.
о да, я бы сказал, вся прога сплошная ошибка )

Цитата Сообщение от DrOffset Посмотреть сообщение
По-хорошему работа с сетью - это должен быть отдельный класс, который вы отдельно оттестируете
Потрясающее раскрытие мне глаз ) На тот момент, мне казалось это через чур: создавать целый класс для 2х методов передачи-приема пакетов.

Цитата Сообщение от DrOffset Посмотреть сообщение
Сама же логика должна быть отделена от GUI:
А вот тут у меня идет некоторое недопонимание: взятие текста из текстового окна "wxTextCtrlIp"
Цитата Сообщение от Palich Посмотреть сообщение
std::string stringIp = (m_darrayTextCtrlIp [aI] ->GetLineText (0)).ToStdString();
должно быть отделено ? т.е. нельзя неосновным потоком выполнять этот код ?

Цитата Сообщение от DrOffset Посмотреть сообщение
чтобы вашу логику можно было в другую GUI-подсистему сунуть, считайте что цель достигнута.
Сделал, впихнул. Есть отдельный класс, в этом классе нет ничего, что связано с графической библиотекой. Правда, пришлось нагородить\усложнить собственными событиями для сигнализации основному потоку обработать результат работы с сетью.

Цитата Сообщение от DrOffset Посмотреть сообщение
А все это к чему? К простоте.
Начинается у меня просто, заканчивается говнокодом



В общем сделал, все запускается, работает.
Пока делал, нашел пару ошибок, о которых бы и не вспомнил.

Добавлено через 3 минуты
Цитата Сообщение от Aledveu Посмотреть сообщение
что мешает запустить в отладчике в линуксе? и посмотреть где беда
отладчик сильно помогает мне в неграфических программах, а вот с графической у меня недопонимания, возможно, нужно как-то настроить его, суть в том что он указывает место ошибки не в моих файлах, а в библиотечных, причем как он туда попал, после какой последовательности отработанных моих строчек кода, не ясно. Эм.... надеюсь, я донес мысль ) Писал, имел в виду отладчик, который в ide.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
22.09.2023, 12:21
Цитата Сообщение от Palich Посмотреть сообщение
т.е. нельзя неосновным потоком выполнять этот код ?
Нельзя. Об этом в документации прямым текстом сказано:
When writing a multi-threaded application, it is strongly recommended that no secondary threads call GUI functions. The design which uses one GUI thread and several worker threads which communicate with the main one using events is much more robust and will undoubtedly save you countless problems (example: under Win32 a thread can only access GDI objects such as pens, brushes, device contexts created by itself and not by the other threads).
https://docs.wxwidgets.org/3.0... hread.html

Но я даже не об этом говорил, а о том, что у вас в принципе и логика, и сеть и GUI перемешаны в одном методе. Естественно точки заимодействия логики с GUI все равно останутся, но в идеале это взаимодействие должно быть локализовано, а не происходить в рандомных частях выполнения логики.

Цитата Сообщение от Palich Посмотреть сообщение
как он туда попал, после какой последовательности отработанных моих строчек кода, не ясно
Backtrace не помогает об этом узнать? Пример "неясности" можете привести?

Цитата Сообщение от Palich Посмотреть сообщение
Начинается у меня просто, заканчивается говнокодом
Кто бы что не говорил, но в программировании нужно не только самостоятельно писать, но и читать (книжки и чужой код), иначе никакого прогресса не будет.
0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
22.09.2023, 14:22  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Backtrace не помогает об этом узнать? Пример "неясности" можете привести?
пойду читать что это такое.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.09.2023, 14:22
Помогаю со студенческими работами здесь

Ошибка в коде (Ошибка сегментирования (core dumped)
Добрый день. Подскажите пожалуйста, где ошибка в коде? char ch; string s; while ((ch = cin.get()) != '0' ) ...

Ошибка сегментирования
Добрый день, возникла проблема: Вот программа, суть из исходного файла у слов удаляется окончание 's' (если оно присутствует), плюс даны...

ошибка сегментирования
При запуске скомпилированной (gcc) программы выскакивает ошибка сегментирования, а при запуске ее же в дебагере (gdb) -- program exited...

Ошибка сегментирования
Здравствуйте! Подскажите, пожалуйста, почему программа выводит &quot;Ошибка сегментирования&quot;. #include &lt;stdlib.h&gt; #include...

Ошибка сегментирования.
Всем доброго времени суток! Помогите пожалуйста разобраться в чем дело, пишу программу( суть найти путь в дереве, но думаю это не будет...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru