LINUX.ORG.RU

pthread не заходит в функцию потока


0

2

Есть потоки, и есть функция, которую поток должен вызывать. В самом начале функции потока есть печаталка, сигнализирующая о том, что поток эту функцию вызывал

printf("\n%s", "tread_func entered");

Проблема вот в чем, - если я делаю потоки по дефолту ( pthread_create....pthread_join ), то всё работает. Однако, если я в аттрибутах потока ставлю PTHREAD_CREATE_DETACHED , то в функцию потока поток заходить перестает). Причем, если вызвать много этих поток (к примеру в цикле штук 10), тогда временами заходит, а если один, то нет.

Вот так делаю:

pthread_t thread;
    pthread_attr_t attr; //threads attributes
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    int i;
    for (i = 0; i < 10; i++) {
        state = pthread_create(&thread, &attr, thread_func, NULL);
        if (state == 0) printf ("\n%s","thread created");
    }
pthread_attr_destroy(&attr);
Скажите пожалуйста, что не так ?

Построчная буферизация stdout

printf(«%s\n», «blah-blah»);

eXire ★★
()

http://linux.die.net/man/3/pthread_create

When a detached thread terminates, its resources are automatically released back to the system: it is not possible to join with the thread in order to obtain its exit status. Making a thread detached is useful for some types of daemon threads whose exit status the application does not need to care about.

Иными словами, твои потоки тупо не успевают начать работу, как приложение завершается, ибо джоинам детачнутые потоки до фени.

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

А как с этим бороться ? Насколько я понял, в main надо как то сделать так, чтобы main не завершался, пока не завершатся потоки. Но раз их статус нельзя проверить, то как это сделать ? Пока ничего не приходит на ум кроме создания дополнительного обычного (не detached) потока после всех остальных, но наверное это неправильно.

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

То, что Вы хотите, называется синхронизацией потоков. Posix имеет много примитивов синхронизации.

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

Зачем ты создаёшь DETACHED поток, и потом хочешь дождаться его завершения?

Может просто создать обычный поток?

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

Нет, к сожелению обычный поток не подходит, надо именно detached (требования такие, т.к. надо сделать так, чтобы потоки одновременно работали. А в обычном они по очереди, насколько я понял).

Как наиболее просто их синхронизировать ? Возможно ли это сделать, не заморачиваюсь семафорами и мьютексами.

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

чтобы потоки одновременно работали. А в обычном они по очереди, насколько я понял

-_-

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

Нет, к сожелению обычный поток не подходит, надо именно detached (требования такие, т.к. надо сделать так, чтобы потоки одновременно работали. А в обычном они по очереди, насколько я понял).

Кажется, ты что-то глобально не понимаешь.

Если ты разом запустишь 10 joinable-потоков, а потом им всем сделаешь по очереди join, то работать они все будут параллельно.

Если ты запустишь joinable-поток, сделаешь ему join, потом запустишь другой поток, сделаешь ему join, и так далее, то ессно работать они будут последовательно.

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

Если ты разом запустишь 10 joinable-потоков, а потом им всем сделаешь по очереди join, то работать они все будут параллельно.

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

Пытаюсь делать так, но неработает (иногда 1 раз заходит в ф-цию потока, иногда не заходит совсем)

int i = 0;
    int id[100];
    for (i; i < 10; i++)
    {
        pthread_create(&thread, NULL, thread_func, &id[i]);
    }
    for (i; i < 10; i++) pthread_join(thread, &id[i]);
Zabroid
() автор топика
Ответ на: комментарий от Zabroid

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

Тебе достаточно завести массив с элементами pthread_t нужного размера.

Пытаюсь делать так

Клиника. Почитай хотя бы, что за аргументы у pthread_create и зачем они нужны. То же самое с pthread_join.

Домашнее задание - подумать, чему равно значение thread после первого цикла и почему происходит join на один и тот же поток во втором цикле.

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

Тебе достаточно завести массив с элементами pthread_t нужного размера

Вот так ?

pthread_t thread[100];
А как потом работать с ним ?
pthread_join[i](thread, NULL);
не компилируется разумеется.

 подумать, чему равно значение thread после первого цикла и почему происходит join на один и тот же поток во втором цикле

Очевидно равно последнему потоку, и заходит туда же. Но ведь я делал для каждого потока (и джойна соответственно) свой идентификатор &id , так что по идее все нормально должно быть.

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

pthread_join(thread, NULL);

Почитай уже, что ли, какую-нибудь книгу по C...

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

Сейчас вот так делаю, и вроде работает. Но нет уверенности в том, что они (потоки) работают одновременно. Как в этом убедиться ?

int i = 0;
   
    for (i; i < 10; i++)
    {
        
        pthread_create(&thread[i], NULL, thread_func, NULL);
        pthread_join(thread[i], NULL);
    }
Zabroid
() автор топика
Ответ на: комментарий от Zabroid

Они не работают одновременно. Очевидно же из кода.

for (i;

Где тебя такому научили? Выброси этот источник «знаний».

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

Они не работают одновременно. Очевидно же из кода

Тогда как сделать так, что бы работали одновременно ? Я уже способа 4 разных пробовал (выше все выкладывал).

А что в тебе в цикле моем не нравится ? То, что переменную счетчик лучше обьявлять прямо в коде цикла? А не получается, т.к. тут чистый С и при компиляции вылезает ошибко error: 'for' loop initial declaration used outside C99 mode

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

А что в тебе в цикле моем не нравится ?

Он хочет

int i;
for (i = 0; ...

потому что если сделать

int i = 0;

for (i; ...

for (i; ...

то второй цикл просто не выполнится. Попробуй компилировать с -Wall (-Wunused-value).

А не получается, т.к. тут чистый С и при компиляции вылезает ошибко error: 'for' loop initial declaration used outside C99 mode

Почему бы не использовать C99?

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

Тогда как сделать так, что бы работали одновременно ?

Тут есть пример.

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

Ну я с99 видимо и использую. свою ошибку со вторым циклом увидел (ведь в 0 не сбрасывается i) Сейчас делаю так

int i = 0;
   
    for (i; i < 10; i++)
    {
        
        pthread_create(&thread[i], NULL, thread_func, NULL);
        
    }
    for (i = 0; i < 10; i++) pthread_join(thread[i], NULL);
Так ?

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

Ну я с99 видимо и использую.

В духе с99 это с объявлением локального для тела цикла счётчика прямо в первой из трёх частей for:

pthread_t threads[10];

for (int i = 0; i < 10; ++i)
    pthread_create(&threads[i], NULL, your_function, NULL);

for (int i = 0; i < 10; ++i)
    pthread_join(threads[i], NULL); 
quasimoto ★★★★
()

годный вброс! я бы так не смог.

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

Уже лучше, но все равно говно. Если уж ты не используешь инициализацию в for, то пиши хотя бы так:

for (; i < 10; i++)

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

Да пофиг на циклы, я не понимаю как мне сделать потоки работающими одновременно. (в идеале не мешающими друг другу). Потому что то, что приходило мне в голову, не работает.

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

Сначала учатся ходить, и только потом бегать.

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

при попытке сделать так я как раз и получаю

Укажи стандарт опцией своему компилятору:

$ cc -std=c99 ...
quasimoto ★★★★
()
Ответ на: комментарий от Zabroid

Да пофиг на циклы, я не понимаю как мне сделать потоки работающими одновременно

Дык сходи по ссылке по ссылке :)

quasimoto ★★★★
()
pthread_mutex_t mux=PTHERAD_MUTEX_INITIALIZER; // защищает счётчик нитей
int count=0; // соб-сно счётчик нитей
pthread_cond_t cond=PTHREAD_COND_INITALIZER; // сигнал о завершении последней нити
/** нитка - сильно-сильно псевдокод */
void my_thread(void *p) {
 ...//bla-bla-bla
 pthread_mutex_lock(&mux);
 if (count) {
   count--;
   if (!count) pthread_cond_signal(&cond); // ниток больше нет - передали сигнал
 }
 pthread_mutex_unlock(&mux);
}
/** main - то-же выдержки */
int main() {
 pthread_mutex_lock(&mux);
 for(t=0;t<MAXIMUM_MY_THREADS;t++) {
   pthread_create(&any_tid,my_thread,NULL);
   count++;
 }
 pthread_mutex_unlock(&mux);
 ....// bla-bla-bla
 /* ждём завершения последней нити */
 pthread_cond_wait(&cond,&mux);
 
}
MKuznetsov ★★★★★
()
Ответ на: комментарий от anonymous

форматирование сожрало скобки, короче они после thread нужны

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