Автор Тема: Несколько потоков в одной функции  (Прочитано 4450 раз)

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

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Могут ли разные потоки в одной функции портить локальные переменные друг друга в ней?
 

Оффлайн qupl

  • Главный модератор
  • Ветеран
  • *****
  • Сообщений: 5016
  • memento mori
  • Jabber: qupl@jabber.ru
Re: Несколько потоков в одной функции
« Ответ #1 : 04 Июль 2012, 20:04:29 »
Мммм, а что подразумевается под несколькими потоками в одной функции?
Несколько потоков в одном приложении, одновременно обращающиеся/изменяющие к одним и тем же переменным вполне могут их "портить". Опять же, какой язык программирования? Лучше пример кода показать.

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Re: Несколько потоков в одной функции
« Ответ #2 : 04 Июль 2012, 20:45:17 »
Приложение одно. Язык Си. Потоков два. Вызывают одну функцию. Через непостоянное количество вызовов происходит ошибка сегментации. (если поток один ошибка ни разу не происходила).
 

Оффлайн Olej

  • Старожил
  • ****
  • Сообщений: 521
Re: Несколько потоков в одной функции
« Ответ #3 : 06 Июль 2012, 00:45:25 »
Приложение одно. Язык Си. Потоков два. Вызывают одну функцию. Через непостоянное количество вызовов происходит ошибка сегментации. (если поток один ошибка ни разу не происходила).
Элементарно (может).
см. http://rus-linux.net/nlib.php?name=/MyLDP/BOOKS/Linux-tools/index.html - там в последней части есть достаточно примеров.
Или - http://www.books.ru/search.php?s[query]=QNX&x=0&y=0&s[go]=1&s[type_of_addon]=all:

(где-то была ссылка для скачивания книги, попадётся - сброшу).

P.S. вот здесь: http://www.flibusta.net/a/36261
« Последнее редактирование: 06 Июль 2012, 00:47:31 от Olej »
 

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Re: Несколько потоков в одной функции
« Ответ #4 : 15 Июль 2012, 12:33:36 »
Последняя ссылка к сожалению не живая, а из первой я не все понял.

То что общая глобальная переменная может портится, это понятно. А могут ли портится локальные переменные функции (и вызываемых из нее функций)? и области памяти выделенные malloc, на которые указывают локальные переменные?
 

Оффлайн qupl

  • Главный модератор
  • Ветеран
  • *****
  • Сообщений: 5016
  • memento mori
  • Jabber: qupl@jabber.ru
Re: Несколько потоков в одной функции
« Ответ #5 : 16 Июль 2012, 06:36:09 »
mihail_1,  без примера кода вопрос можно обсуждать бесконечно.

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Re: Несколько потоков в одной функции
« Ответ #6 : 24 Июль 2012, 18:43:15 »
Пример в три тысячи строк не удобен для форума, да похоже и не нужен - все ошибки в библиотечных функциях.
Одна из библиотек для работы с mysql. Его нельзя многопоточно?! (каждый поток коннектится самостоятельно используя свой список переменных)
А вот как узнать что из libc-2.7.so не поддерживает многопоточности совсем не понятно.
 

Оффлайн Olej

  • Старожил
  • ****
  • Сообщений: 521
Re: Несколько потоков в одной функции
« Ответ #7 : 25 Июль 2012, 00:28:22 »
Пример в три тысячи строк не удобен для форума, да похоже и не нужен - все ошибки в библиотечных функциях.
1. всегда можно смоделировать пример в 10 строк который показывает проблему.

2. я за много лет ещё не встречал ни одного ни коллеги ни студента, которые бы не утверждали, что тупые не они, а "библиотечные функции"  ;D 

Одна из библиотек для работы с mysql. Его нельзя многопоточно?! (каждый поток коннектится самостоятельно используя свой список переменных)
А вот как узнать что из libc-2.7.so не поддерживает многопоточности совсем не понятно.

3. в стандартах POSIX и в описаниях библиотечных функций всегда указывается thread-safe ... или нет.
Вдумчиво читаем матчасть  ;)
 

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Re: Несколько потоков в одной функции
« Ответ #8 : 25 Июль 2012, 17:32:25 »
 1 - смоделировать проблему можно когда ее знаешь, а когда через пару часов работы трех тысяч строк с 33 потоками вылезает segmentation fault, не совсем ясно что моделировать.
 2 - почитайте высказывания о функции iconv, которая вместо возвращения кода ошибки вызывает аварийный останов программы. (я как и многие помучавшись заменил ее своей версией - хоть эта часть программы больше не глючит, а проблемы с ней были выявлены еще в однопоточном тестировании)
 3 - это похоже действительно полезная часть ответа, но посмотрев для функций malloc, printf, sprintf, atoi в манах posix на opennet я ни в одном из описаний не нашел слова thread.
Я не в том смотрю описания функций?

Сообщение объединено: 25 Июль 2012, 22:10:01
Может кто даст ссылочку где "в стандартах POSIX и в описаниях библиотечных функций всегда указывается thread-safe ... или нет".
« Последнее редактирование: 25 Июль 2012, 22:10:01 от mihail_1 »
 

Оффлайн Olej

  • Старожил
  • ****
  • Сообщений: 521
Re: Несколько потоков в одной функции
« Ответ #9 : 26 Июль 2012, 20:15:33 »
3 - это похоже действительно полезная часть ответа, но посмотрев для функций malloc, printf, sprintf, atoi в манах posix на opennet я ни в одном из описаний не нашел слова thread.
Я не в том смотрю описания функций?
Сообщение объединено: Вчера в 22:10:01Может кто даст ссылочку где "в стандартах POSIX и в описаниях библиотечных функций всегда указывается thread-safe ... или нет".

во-первых, я говорил не про man, а про стандарт POSIX: man-ы пишут любители, POSIX пишут профессионалы - очень большая разница. 

вот здесь в обсуждении есть ссылки на сами тексты стандарта POSIX.
особенно вам может быть интересен там раздел Rationale.

очень много примечаний о thread-safe в описаниях библиотек ОС QNX и Solaris ... главы из этих описаний можете в интернет найти.
вот ссылка на книгу, что я показывал выше: http://www.flibusta.net/a/36261 - она писалась (проверялась) на QNX, там есть много о thread-safe
(если вы о этой ссылке говорите "битая", то это неправда, я только-что проверил, вот вам совсем прямая ссылка: http://www.flibusta.net/b/129432)

многие функции и так понятны, что они не thread-safe: которые содержат satic данные в себе, возвращают побочный эффект через параметры и т.д.
часто такие функции находятся в самых неожиданных местах, например, несколько функций в строчной библиотеке str*() - куда уж проще!

если вы минимально дружите с примитивами синхронизации (хоть с самыми элементраными), то и работу с not thread-safe функциями можете сделать безопасной, кроме того, расстановкой примитивов синхронизации на фрагменты вашего огромного кода, который вас так пугает ;), вы можете легко локализлвать место SIGSEGV.

 

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Re: Несколько потоков в одной функции
« Ответ #10 : 27 Июль 2012, 21:28:04 »
Делать безопасными not thread-safe функции синхронизацией почти бессмысленно. С тем же успехом можно оставить один поток. В коде в основном работа со строками и вызовы mysql. (имеется много ядер и много дисков - чтобы всех загрузить сделано много потоков, а если потоки будут работать поочереди зачем они?)
Для части функций видимо напишу свои аналоги, что с делать mysql пока непонятно.
 

Оффлайн Olej

  • Старожил
  • ****
  • Сообщений: 521
Re: Несколько потоков в одной функции
« Ответ #11 : 27 Июль 2012, 23:47:06 »
Делать безопасными not thread-safe функции синхронизацией почти бессмысленно. С тем же успехом можно оставить один поток.
Абсолютное непонимание принципов параллелизма и синхронизации!

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

Посмотрите вот это: Параллелизм и синхронизация - это внутри ядра Linux, не совсем то, но там можно видеть элементы того, о чём я говорю.

 

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Re: Несколько потоков в одной функции
« Ответ #12 : 10 Август 2012, 20:18:36 »
==16927== Thread 2:
==16927== Syscall param socketcall.recvfrom(buf) points to unaddressable byte(s)
==16927==    at 0x530ABA1: recv (in /lib/libpthread-2.7.so)
        l=recv(sock,&buf_work[l_buf],max_buf-1-l_buf,0);
        if(l>0)
        {
          l_buf+=l;
        }
        if(l==0)break;
Шансов передать плохой указатель или длинну нет, но ошибка есть (хотя 1 на примкрно 100000 вызовов)
приведенный код выполняется одним потоком в многопоточном приложении, использует глобальные и свои внутренние переменные.
Что исправлять?
 

Оффлайн qupl

  • Главный модератор
  • Ветеран
  • *****
  • Сообщений: 5016
  • memento mori
  • Jabber: qupl@jabber.ru
Re: Несколько потоков в одной функции
« Ответ #13 : 10 Август 2012, 20:28:50 »
mihail_1
1) следить за выходом за пределы буфера
2) проверить начальную инициализацию переменных
3) проверить, что не бывает ситуации когда под буфер не выделено памяти
4) ит.д.

Оффлайн mihail_1

  • Местный житель
  • ***
  • Topic Author
  • Сообщений: 176
Re: Несколько потоков в одной функции
« Ответ #14 : 10 Август 2012, 21:25:31 »
буфер выделяется один раз в начале до запуска потока
l_buf обнуляется при установке каждого соединения
max_buf константа
и кроме того зачем-то есть
EBADF
Аргумент s является неверным дескриптором.
ENOTSOCK
Аргумент s не является сокетомАргумент s является неверным дескриптором
EFAULT
Указатель на приемный буфер указывает вне адресного пространства процесса.
EINVAL
Передан неверный аргумент.
 

Теги:
 

Несколько сценариев одновременно (bash)

Автор seisros

Ответов: 5
Просмотров: 8020
Последний ответ 31 Август 2013, 04:17:10
от smallNix