Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Многопоточное программирование под Gtk# в MonoDevelop  (Прочитано 1261 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Mixim

  • Автор темы
  • Участник
  • *
  • Сообщений: 114
    • Просмотр профиля
Уже несколько дней бьюсь над задачей, согласно которой необходимо с использованием параллельного программирования найти в некотором тексте количество вхождений некоторого ключа, т.е. примерно следующее (обрамил в цитату):
Цитировать
подгружаем текст из выбранного пользователем файла, получаем от пользователя ключ для поиска, например строку "это мой ключ", при каждом нахождении указанного ключа, увеличиваем счетчик
Написал два соответствующих класса для решения этой задачи (один ищет вхождения в файле без применения многопоточности, другой, используя первый, ищет информацию с применением нескольких потоков), запускаю в консоли - все нормально работает, копирую классы в GUI-программу, вычисляемую информацию вывожу после изменения процента выполнения на величину N с помощью кода:
protected void TextFindCallback1(System.Object Sender, Double PercentComplete, String ElapsedTime, System.Numerics.BigInteger QuantityOfMatchesFound)
{
textview1.Buffer.Text+=String.Format("\n TextFindCallback1; Sender={0}; PercentComplete={1}; ElapsedTime={2}; Quantity={3}", Sender, PercentComplete, ElapsedTime, QuantityOfMatchesFound);
}


protected void TextFindCallback2(System.Object Sender, Double PercentComplete, String ElapsedTime, System.Numerics.BigInteger QuantityOfMatchesFound)
{
textview2.Buffer.Text+=String.Format("\n TextFindCallback2; Sender={0}; PercentComplete={1}; ElapsedTime={2}; Quantity={3}", Sender, PercentComplete, ElapsedTime, QuantityOfMatchesFound);
}

protected void TextFindCallback3(System.Object Sender, Double PercentComplete, String ElapsedTime, System.Numerics.BigInteger QuantityOfMatchesFound)
{
textview3.Buffer.Text+=String.Format("\n TextFindCallback3; Sender={0}; PercentComplete={1}; ElapsedTime={2}; Quantity={3}", Sender, PercentComplete, ElapsedTime, QuantityOfMatchesFound);
}


protected void TextFindCallback4(System.Object Sender, Double PercentComplete, String ElapsedTime, System.Numerics.BigInteger QuantityOfMatchesFound)
{
textview4.Buffer.Text+=String.Format("\n TextFindCallback4; Sender={0}; PercentComplete={1}; ElapsedTime={2}; Quantity={3}", Sender, PercentComplete, ElapsedTime, QuantityOfMatchesFound);
}

protected void TextFindCallback5(System.Object Sender, Double PercentComplete, String ElapsedTime, System.Numerics.BigInteger QuantityOfMatchesFound)
{
textview5.Buffer.Text+=String.Format("\n TextFindCallback5; Sender={0}; PercentComplete={1}; ElapsedTime={2}; Quantity={3}", Sender, PercentComplete, ElapsedTime, QuantityOfMatchesFound);
}
, но в итоге получаю периодическое падение программы без каких-либо явных сообщений о произошедшем исключении. Вот что выдал терминал на запуск и выполнение:
Цитировать
Stacktrace:

  at (wrapper managed-to-native) Gtk.Application.gtk_main () <0xffffffff>
  at Gtk.Application.Run () <0x0000b>
  at ParallelProgrammingLab1.MainClass.Main (string[]) <0x0003f>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <0xffffffff>

Native stacktrace:

   /usr/bin/cli() [0x4961e9]
   /usr/bin/cli() [0x4e6d1f]
   /usr/bin/cli() [0x41dcb7]
   /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x7fa308581cb0]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(+0x1c3a5c) [0x7fa2fdd04a5c]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(+0x1c6912) [0x7fa2fdd07912]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(+0x1c857b) [0x7fa2fdd0957b]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(gtk_text_layout_validate_yrange+0x1e1) [0x7fa2fdd22de1]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(+0x1f025c) [0x7fa2fdd3125c]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(+0x1f246e) [0x7fa2fdd3346e]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(+0x1f24a9) [0x7fa2fdd334a9]
   /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0(+0x1de77) [0x7fa2fd8ace77]
   /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x135) [0x7fa2f7b01ab5]
   /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x47de8) [0x7fa2f7b01de8]
   /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_loop_run+0x72) [0x7fa2f7b021e2]
   /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0(gtk_main+0xa7) [0x7fa2fdc74c77]
   [0x402a02a5]

Debug info from gdb:

Could not attach to process.  If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Операция не позволяется.
No threads.

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================

Аварийный останов (сделан дамп памяти)
Содержимое файла "10-ptrace.conf", который указан в выводе:
Цитировать
#ряд комментариев
kernel.yama.ptrace_scope = 1
Пытался запустить программу от имени root, но все точно также. В классе использую семафоры, которые позволяют запускаться не более чем 2 потокам одновременно. Предполагаю, что проблема заключается в одновременном обращении к элементам формы из разных потоков, т.е. в методах, которые приведены выше, но как их тогда исправить? Можете подсказать в чем проблема и как её решить?
Сделаю поправку: проект тестовый, поэтому прошу не обращать внимания на дефолтные имена элементов управления (textview4, textview5 и т.д.)

Оффлайн DemonN_nn

  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Я, правда, не разобрался в том, что именно у вас там не так работает, но у меня закралось смутное сомнение...

Какой именно поток обновляет UI, а какие потоки готовят данные для этих форм и синохронизованн ли обмен данными между ними?
Очень часто при программировании многопоточных вычислений забывают про основной поток, работающий с пользовательским интерфейсом.

Оффлайн Progger

  • Любитель
  • *
  • Сообщений: 95
    • Просмотр профиля
Как указали выше, обновление GUI должно происходить в главном потоке. Реализуется это с помощью Control.Invoke или Control.BeginInvoke

 

Страница сгенерирована за 0.019 секунд. Запросов: 22.