не выполняется тред (не пойму в чём дело)

Модератор: Модераторы разделов

Аватара пользователя
pluton8
Сообщения: 108
ОС: Arch GNU/Linux

не выполняется тред

Сообщение pluton8 »

привет всем!
написал прогу для знакомства с тредами в линуксе:

Код: Выделить всё

#include <iostream>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>

struct msgbuff
{
    long mtype;
    char data;
};

void* thr1_func(void* arg)
{
    int fd = open("thr2.out", O_CREAT | O_WRONLY, 0660);
    int mq;
    if ((mq = msgget(80, IPC_CREAT | IPC_EXCL | 0660)) == -1)
    {
        if (errno != EEXIST)
        {
            perror("msgget()");
            return (void*)-1;
        }
        mq = msgget(80, 0);
    }
    printf("mq2=%u\n", mq);
    msgbuff mb = {0, 0};
    while (mb.data != '!')
    {
        msgrcv(mq, &mb, sizeof mb, 81, 0);
        write(fd, &mb.data, 1);
    }
    printf("222\n");
    close(fd);
    return NULL;
}

int main()
{
    pthread_t thr1;
    pthread_create(&thr1, NULL, thr1_func, NULL);
    int mq;
    if ((mq = msgget(80, IPC_CREAT | IPC_EXCL | 0660)) == -1)
    {
        if (errno != EEXIST)
        {
            perror("msgget()");
            return -1;
        }
        mq = msgget(80, 0);
    }
    printf("mq1=%u\n", mq);
    int fd = open("thr2.cpp", O_RDONLY, 0660);
    char c;
    struct msgbuff mb;
    while (read(fd, &c, 1) != 0)
    {
        //printf("%c", c);
        if (c == 'e' || c == 'y' || c == 'u' || c == 'i' || c == 'o' || c == 'a')
        {
            mb.mtype = 81;
            mb.data = c;
            msgsnd(mq, &mb, sizeof mb, 0);
        }
    }
    mb.mtype = 81;
    mb.data = '!';
    msgsnd(mq, &mb, sizeof mb, 0);
    printf("111\n");
    msgctl(mq, IPC_RMID, NULL);
    close(fd);
    return 0;
}

не выполняется дополнительный тред:

Код: Выделить всё

[user@pluton-linux os]$ g++ thr2.cpp -o thr2 -pthread
[user@pluton-linux os]$ ./thr2
mq1=262144
111
[user@pluton-linux os]$

делал такую же прогу, тока вместо сообщений были семафоры, таже лажа, не идёт :(
помогите, скажите в чём дело?
заранее спасибо!!!
зы. ось Mandriva Linux release 2007.1 (Cooker) for i586
Kernel 2.6.17-13mdv on an i686
THE TRUTH IS OUT THERE
Linux Registered User #450136
Спасибо сказали:
Аватара пользователя
dey
Сообщения: 335
ОС: OpenSuse 11.1

Re: не выполняется тред

Сообщение dey »

На первый взгляд проблема заключается в отсутствии вызова pthread_join() для созданного потока
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Спасибо сказали:
Аватара пользователя
pluton8
Сообщения: 108
ОС: Arch GNU/Linux

Re: не выполняется тред

Сообщение pluton8 »

dey писал(а):
08.01.2008 23:32
На первый взгляд проблема заключается в отсутствии вызова pthread_join() для созданного потока

The pthread_join() function shall suspend execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
а зачем? мне оно не надо. main() читает и отправляет данные, а тред сохраняет
THE TRUTH IS OUT THERE
Linux Registered User #450136
Спасибо сказали:
Аватара пользователя
dey
Сообщения: 335
ОС: OpenSuse 11.1

Re: не выполняется тред

Сообщение dey »

Функция pthread_join() заставляет основной поток ожидать до тех пор пока не завершатся рабочие потоки , и не "присоединяться" к основному . В приведенном коде основной поток завершается не дожидаясь выполнения дочернего .. вроде так
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Спасибо сказали:
Аватара пользователя
pluton8
Сообщения: 108
ОС: Arch GNU/Linux

Re: не выполняется тред

Сообщение pluton8 »

dey, смотри. самая простая прога:

Код: Выделить всё

#include <iostream>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>

void* thr1_func(void* arg)
{
        for (int i = 0; i < 1000; i++)
                printf("2");
        return NULL;
}

int main()
{
        pthread_t thr1;
        pthread_create(&thr1, NULL, thr1_func, NULL);
        for (int i = 0; i < 1000; i++)
                printf("1");
        return 0;
}

по логике, должна выводить 1 и 2 както вперемешку. а что выводит:
[user@pluton-linux os]$ ./thr3
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
111111111111111111111111[user@pluton-linux os]$
ну что это такое?

кстати, както можно посмотреть запущенные треды?
THE TRUTH IS OUT THERE
Linux Registered User #450136
Спасибо сказали:
Аватара пользователя
dey
Сообщения: 335
ОС: OpenSuse 11.1

Re: не выполняется тред

Сообщение dey »

Твоя же программа , немного измененная

Код: Выделить всё

#include <iostream>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>

void* thr1_func(void* arg)
{
        for (int i = 0; i < 10; i++)
                printf("2");
        return NULL;
}

int main()
{
        pthread_t thr1;
        pthread_create(&thr1, NULL, thr1_func, NULL);
        pthread_join(thr1,NULL);
        for (int i = 0; i < 10; i++)
                printf("1");
        return 0;
}

результат

Код: Выделить всё

[dey@martin ~]$ ./thr2
22222222221111111111

както можно посмотреть запущенные треды?

Можно, например pthread_self() возвращает идентификатор потока, аналогично getpid() для процессов
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Спасибо сказали:
Аватара пользователя
halturin
Сообщения: 167
ОС: Linux

Re: не выполняется тред

Сообщение halturin »

pluton8 писал(а):
09.01.2008 00:04
dey, смотри. самая простая прога:

Код: Выделить всё

#include <iostream>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>

void* thr1_func(void* arg)
{
        for (int i = 0; i < 1000; i++)
                printf("2");
        return NULL;
}

int main()
{
        pthread_t thr1;
        pthread_create(&thr1, NULL, thr1_func, NULL);
        for (int i = 0; i < 1000; i++)
                printf("1");
        return 0;
}

по логике, должна выводить 1 и 2 както вперемешку. а что выводит:
[user@pluton-linux os]$ ./thr3
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
111111111111111111111111[user@pluton-linux os]$
ну что это такое?

кстати, както можно посмотреть запущенные треды?


попробуй основным потоком и фоновым писать в один файл.
Спасибо сказали:
Аватара пользователя
indie
Сообщения: 87

Re: не выполняется тред

Сообщение indie »

pluton8 писал(а):
09.01.2008 00:04
dey, смотри. самая простая прога:

Код: Выделить всё

#include <iostream>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>

void* thr1_func(void* arg)
{
        for (int i = 0; i < 1000; i++)
                printf("2");
        return NULL;
}

int main()
{
        pthread_t thr1;
        pthread_create(&thr1, NULL, thr1_func, NULL);
        for (int i = 0; i < 1000; i++)
                printf("1");
        return 0;
}

по логике, должна выводить 1 и 2 както вперемешку. а что выводит:
[user@pluton-linux os]$ ./thr3
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
11111111111111111111111111111111111111111111111111111111111111111111111111111111
1
111111111111111111111111[user@pluton-linux os]$
ну что это такое?

кстати, както можно посмотреть запущенные треды?

Не будет, ибо printf сбрасывает на экран символы пока строка не заполниться. Проверь свою логику с символом перехода на следующую строку aka '\n'. т.е. printf("1\n"); и printf("2\n");
Спасибо сказали:
Аватара пользователя
pluton8
Сообщения: 108
ОС: Arch GNU/Linux

Re: не выполняется тред

Сообщение pluton8 »

indie писал(а):
09.01.2008 16:22
Не будет, ибо printf сбрасывает на экран символы пока строка не заполниться. Проверь свою логику с символом перехода на следующую строку aka '\n'. т.е. printf("1\n"); и printf("2\n");

я сделал так в цикле:
{
printf("1");
fflush(NULL);
}
ответ тотже. выводятся только единицы
THE TRUTH IS OUT THERE
Linux Registered User #450136
Спасибо сказали:
d_n_k
Сообщения: 636
ОС: Gentoo GNU/Linux

Re: не выполняется тред

Сообщение d_n_k »

все сказанное есть имхо...
Спасибо сказали:
Аватара пользователя
pluton8
Сообщения: 108
ОС: Arch GNU/Linux

Re: не выполняется тред

Сообщение pluton8 »

переделал прогу чтобы в конце вызывалась pthread_join():

Код: Выделить всё

#include <iostream>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>

struct msgbuff
{
    long mtype;
    char data;
};

void* thr1_func(void* arg)
{
    int fd2 = open("thr2.out", O_CREAT | O_WRONLY, 0660);
    printf("fd=%u, err=%s\n",fd2, strerror(errno));
    int mq;
    if ((mq = msgget(80, IPC_CREAT | IPC_EXCL | 0660)) == -1)
    {
        if (errno != EEXIST)
        {
            perror("msgget()");
            return (void*)-1;
        }
        mq = msgget(80, 0);
    }
    printf("mq2=%u\n", mq);
    msgbuff mb = {0, 0};
    while (mb.data != '!')
    {
        int r = msgrcv(mq, &mb, sizeof mb, 81, 0);
        //printf("r=%u d=%c, ", r, mb.data);
        int a=write(fd2, &mb.data, 1);
        printf("fd=%d, ", /*r, mb.data, */fd2);
    }
    printf("222\n");
    printf("fd=%d", fd2);
    int r=close(fd2);
    printf("r=%d err=%s\n", r, strerror(errno));
    return NULL;
}

int main()
{
    pthread_t thr1;
    pthread_create(&thr1, NULL, thr1_func, NULL);
    int mq;
    if ((mq = msgget(80, IPC_CREAT | IPC_EXCL | 0660)) == -1)
    {
        if (errno != EEXIST)
        {
            perror("msgget()");
            return -1;
        }
        mq = msgget(80, 0);
    }
    printf("mq1=%u\n", mq);
    int fd = open("thr2.cpp", O_RDONLY, 0660);
    char c;
    struct msgbuff mb;
    while (read(fd, &c, 1) != 0)
    {
        //printf("%c", c);
        printf("fd1=%d",fd);
        if (c == 'e' || c == 'y' || c == 'u' || c == 'i' || c == 'o' || c == 'a')
        {
            mb.mtype = 81;
            mb.data = c;
            msgsnd(mq, &mb, sizeof mb, 0);
        }
    }
    mb.mtype = 81;
    mb.data = '!';
    msgsnd(mq, &mb, sizeof mb, 0);
    pthread_join(thr1, NULL);
    printf("111 fd=%d\n", fd);
    msgctl(mq, IPC_RMID, NULL);
    close(fd);
    return 0;
}

теперь main() ждёт завршения треда. почему они не переключались в той проге?
возникла другая проблема: fd2 в треде меняется САМ. вот:

Код: Выделить всё

[user@pluton-linux os]$ ./thr2
mq1=524288
fd1=3fd1=3fd1=3fd1=3 ... fd1=3fd1=3fd1=3fd=5, err=Success
mq2=524288
fd=1777879268, fd=1979205860, fd=1710770404, fd=1777879268, fd=1878542564, fd=1710770404, fd=1643661540, fd=1777879268, fd=1979205860, fd=1710770404, fd=1710770404, fd=1643661540, fd=1777879268, fd=1979205860, fd=1710770404, fd=1777879268, fd=1979205860, fd=1710770404, fd=1710770404, fd=1878542564, fd=1777879268, fd=1979205860, fd=1710770404, fd=2046314724, fd=1777879268, fd=1979205860, fd=1710770404, fd=2046314724, fd=1777879268, fd=1979205860, fd=1979205860, fd=1878542564, fd=2046314724, fd=1710770404, fd=1643661540, fd=1643661540, fd=1643661540, fd=1878542564, fd=1777879268, fd=1979205860, fd=1878542564, fd=1777879268, fd=1643661540, fd=1777879268, fd=1878542564, fd=1710770404, fd=1878542564, fd=1979205860, fd=1777879268, fd=1979205860, fd=1710770404, fd=1710770404, fd=1878542564, fd=1710770404, fd=1878542564, fd=1777879268, fd=1777879268, fd=1710770404, fd=1777879268, fd=1710770404, fd=1878542564, fd=1710770404, fd=1878542564, fd=1710770404, fd=1710770404, fd=1979205860, fd=1878542564, fd=1777879268, fd=1710770404, fd=1777879268, fd=1979205860, fd=1979205860, fd=1777879268, fd=1710770404, fd=1643661540, fd=1643661540, fd=1777879268, fd=1777879268, fd=1710770404, fd=1878542564, fd=1777879268, fd=1979205860, fd=1643661540, fd=1643661540, fd=1777879268, fd=1643661540, fd=1777879268, fd=1710770404, fd=1643661540, fd=1643661540, fd=1777879268, fd=1643661540, fd=1643661540, fd=1777879268, fd=1777879268, fd=1777879268, fd=1878542564, fd=1710770404, fd=1777879268, fd=1710770404, fd=1710770404, fd=1878542564, fd=1710770404, fd=1878542564, fd=1710770404, fd=1979205860, fd=1777879268, fd=1643661540, fd=1777879268, fd=1710770404, fd=1643661540, fd=1710770404, fd=1643661540, fd=1710770404, fd=1643661540, fd=1710770404, fd=1979205860, fd=1777879268, fd=1777879268, fd=1710770404, fd=1777879268, fd=1710770404, fd=1878542564, fd=1710770404, fd=1878542564, fd=1710770404, fd=1710770404, fd=1979205860, fd=1710770404, fd=1777879268, fd=1979205860, fd=1777879268, fd=1878542564, fd=1710770404, fd=1643661540, fd=1979205860, fd=1979205860, fd=1777879268, fd=1710770404, fd=1710770404, fd=1643661540, fd=1777879268, fd=1777879268, fd=1777879268, fd=1710770404, fd=2046314724, fd=1979205860, fd=1777879268, fd=1878542564, fd=1643661540, fd=2046314724, fd=1710770404, fd=1643661540, fd=1643661540, fd=1777879268, fd=1710770404, fd=1878542564, fd=2046314724, fd=1710770404, fd=1643661540, fd=1643661540, fd=1777879268, fd=1710770404, fd=1878542564, fd=1710770404, fd=1643661540, fd=1878542564, fd=1777879268, fd=1777879268, fd=1878542564, fd=1710770404, fd=1710770404, fd=1979205860, fd=184043748, 222
fd=184043748r=-1 err=Bad file descriptor
111 fd=3

почему???
THE TRUTH IS OUT THERE
Linux Registered User #450136
Спасибо сказали:
Galaxy Master
Сообщения: 142
ОС: Debian GNU/Linux

Re: не выполняется тред

Сообщение Galaxy Master »

господа все просто!

ваши потоки завершались быстрее, чем планировщик их начинал переключать

(это я о проге с 1000 printf)

поэтому и не получалось увидеть 1212121

чтоб увидеть то что бы хотите или сделайте цикл не 1000 оборотов а больше (лучше бесконечный)
и/или добавьте в него ф-цию принудительной отдачи управления системе, например
usleep(...); с паузой от 0 до....
или еще что-то, чтоб ваши потоки (как главный так и второй) не завершались быстрее чем период квантования планировщика
тогда и увидите переключение.




dey писал(а):
09.01.2008 00:38
Твоя же программа , немного измененная

Код: Выделить всё

#include <iostream>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>

void* thr1_func(void* arg)
{
        for (int i = 0; i < 10; i++)
                printf("2");
        return NULL;
}

int main()
{
        pthread_t thr1;
        pthread_create(&thr1, NULL, thr1_func, NULL);
        pthread_join(thr1,NULL);
        for (int i = 0; i < 10; i++)
                printf("1");
        return 0;
}

результат

Код: Выделить всё

[dey@martin ~]$ ./thr2
22222222221111111111

както можно посмотреть запущенные треды?

Можно, например pthread_self() возвращает идентификатор потока, аналогично getpid() для процессов



а это вообще смешно!
pthread_create(&thr1, NULL, thr1_func, NULL); - ожидает завершения второго потока, а потом начинается выполнение
for (int i = 0; i < 10; i++)
printf("1");

во время выполнения потока 2 - основной поток СПИТ!

поэтому этот код ВСЕГДА даст 22222222221111111111 на зависимо ни от чего!
Спасибо сказали: