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

Тема в разделе "WASM.UNIX", создана пользователем pluton, 6 янв 2008.

  1. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    всем привет!
    написал маленькую программку для знакомства с тредами в линуксе:
    Код (Text):
    1. #include <iostream>
    2. #include <pthread.h>
    3. #include <fcntl.h>
    4. #include <sys/sem.h>
    5.  
    6. struct sembuf rel1 = {0, 1, 0};
    7. struct sembuf cap1 = {0, -1, 0};
    8. int sem1;
    9. char c;
    10.  
    11. void* thread1_func(void* arg)
    12. {
    13.     int fd = open("thr_file", O_WRONLY|O_CREAT, 0660);
    14.     printf("check\n");
    15.     bool stop = false;
    16.     while (!stop)
    17.     {
    18.         semop(sem1, &cap1, 1);
    19.         printf("%c", c);
    20.         if (c != '!')
    21.             write(fd, &c, 1);
    22.         else
    23.             stop = true;
    24.         semop(sem1, &rel1, 1);
    25.     }
    26.     close(fd);
    27.     return NULL;
    28. }
    29.  
    30. int main()
    31. {
    32.     //int fd = open("/usr/lib/ooo-2.1/share/dict/ooo/th_en_US_v2.dat", O_RDONLY, 0660);
    33.     int fd = open("thr.cpp", O_RDONLY, 0660);
    34.     sem1 = semget(80, 1, O_CREAT);
    35.     pthread_t thr1;
    36.     pthread_attr_t attr1;
    37.     pthread_attr_init(&attr1);
    38.     int e = pthread_create(&thr1, &attr1, thread1_func, NULL);
    39.     printf("%d--%d\n", thr1, e);
    40.     while (read(fd, &c, 1))
    41.     {
    42.         if (c == 'e' || c == 'y' || c == 'u' || c == 'i' || c == 'o' || c == 'a')
    43.         {
    44.             semop(sem1, &rel1, 1);
    45.             semop(sem1, &cap1, 1);
    46.         }
    47.     }
    48.     c = '!';
    49.     semop(sem1, &rel1, 1);
    50.     semop(sem1, &cap1, 1);
    51.     close(fd);
    52.     return 0;
    53. }
    тред создаётся, но ничего не выполняет:
    Код (Text):
    1. [user@pluton-linux labs]$ g++ thr.cpp -o thr -pthread
    2. [user@pluton-linux labs]$ ./thr
    3. -1211630688--0
    4. [user@pluton-linux labs]$
    что ему не нравится? может я чего пропустил?

    зы. ось: Mandriva Linux release 2007.1 (Cooker) for i586
    Kernel 2.6.17-13mdv on an i686
     
  2. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    1. не надо смешивать System V IPC и POSIX IPC
    2. где у тебя инициализация семафора?
    Код (Text):
    1. ...
    2. struct sembuf zero = {0, 0, 0};
    3. ...
    4. /* инициализация семафора в 0 */
    5. ...
    6. int e = pthread_create(&thr1, &attr1, thread1_func, NULL);
    7. ...
    8. while (read(fd, &c, 1))
    9.     {
    10.         if (c == 'e' || c == 'y' || c == 'u' || c == 'i' || c == 'o' || c == 'a')
    11.         {
    12.             semop(sem1, &rel1, 1);
    13.             semop(sem1, &zero, 1);
    14.         }
    15.     }
    + надо убрать
    Код (Text):
    1. semop(sem1, &rel1, 1);
    из thread1_func
     
  3. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    в смысле посиксовые треды и system семафоры? до мьютексов я ещё не добрался.
    очень нужна? дефолтом ставятся нули и всё тут
    как тогда будет освобождаться семафор?
     
  4. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    для портабельности обязательно
    некоторые системы не обнуляют значение семафора
    если начальное значение семафора 0
    то
    после
    Код (Text):
    1. semop(sem1, &rel1, 1);
    в main()
    поток thread1_func сможет выполнить
    Код (Text):
    1. semop(sem1, &cap1, 1);
    а тем временем поток main() будет блокирован на операции
    Код (Text):
    1. semop(sem1, &zero, 1);
    в ожидании нуля
    когда thread1_func() выполнит декрементацию значения счетчика, поток main() разблокируется
     
  5. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    да
    NPTL в Linux реадизован гораздо эффективнее System V IPC
    поэтому лучше для потоков пользоваться NPTL (Native Posix Threads Library)
     
  6. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    это всё хорошо, но тред не выполняется :dntknw:
    над семафорами я подумаю

    желательно использовать mutex?
    библиотека pthread - это и есть NPTL?

    инициализация семафоров - с помощью semctl() ?
     
  7. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    проверял прогу в ubuntu 7.10. немного её изменил. теперь main() создаёт два треда - первый записывает в файл, второй - считывает с файла. вобщем, аналог этой. первый тред один раз выполняется, и всё. дальше работает второй тред - правильно считывает. мне кажется, что они не переключаются.
    кто-то знает в чём дело, и как это исправить?
    Код (Text):
    1. #include <iostream>
    2. #include <pthread.h>
    3. #include <fcntl.h>
    4. #include <sys/sem.h>
    5.  
    6. struct sembuf rel1 = {0, 1, 0};
    7. struct sembuf cap1 = {0, -1, 0};
    8. struct sembuf zero1 = {0, 0, 0};
    9. int sem1;
    10. char c;
    11.  
    12. void* thread1_func(void* arg)
    13. {
    14.     printf("check\n");
    15.     int fd = open("thr_file", O_WRONLY|O_CREAT, 0660);
    16.     bool stop = false;
    17.     while (!stop)
    18.     {
    19.         printf("1111 ");
    20.         semop(sem1, &cap1, 1);
    21.         printf("222 ");
    22.         printf("%c", c);
    23.         if (c != '!')
    24.             write(fd, &c, 1);
    25.         else
    26.             stop = true;
    27.         //semop(sem1, &rel1, 1);
    28.     }
    29.     close(fd);
    30.     return NULL;
    31. }
    32.  
    33. void* thread2_func(void* arg)
    34. {
    35.     int fd = open("thr.cpp", O_RDONLY, 0660);
    36.     while (read(fd, &c, 1))
    37.     {
    38.         //printf("%c* ", c);
    39.         if (c == 'e' || c == 'y' || c == 'u' || c == 'i' || c == 'o' || c == 'a')
    40.         {
    41.             printf("%c* ", c);
    42.             semop(sem1, &rel1, 1);
    43.             //semop(sem1, &cap1, 1);
    44.             semop(sem1, &zero1, 1);
    45.         }
    46.     }
    47.     c = '!';
    48.     semop(sem1, &rel1, 1);
    49.     //semop(sem1, &cap1, 1);
    50.     semop(sem1, &zero1, 1);
    51.     close(fd);
    52.     return NULL;
    53. }
    54.  
    55. int main()
    56. {
    57.     //int fd = open("/usr/lib/ooo-2.1/share/dict/ooo/th_en_US_v2.dat", O_RDONLY, 0660);
    58.     sem1 = semget(80, 1, O_CREAT);
    59.     pthread_t thr1, thr2;
    60.     pthread_attr_t attr;
    61.     pthread_attr_init(&attr);
    62.     int e = pthread_create(&thr1, &attr, thread1_func, NULL);
    63.     printf("%u--%d\n", thr1, e);
    64.     e = pthread_create(&thr2, &attr, thread2_func, NULL);
    65.     printf("%u--%d\n", thr2, e);
    66.     e = pthread_join(thr2, NULL);
    67.     printf("%u\n", e);
    68.     return 0;
    69. }
     
  8. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    сделал туже прогу, только вместо семафоров использую сообщения:
    Код (Text):
    1. #include <iostream>
    2. #include <pthread.h>
    3. #include <fcntl.h>
    4. #include <errno.h>
    5. #include <sys/msg.h>
    6. #include <sys/ipc.h>
    7.  
    8. struct msgbuff
    9. {
    10.     long mtype;
    11.     char data;
    12. };
    13.  
    14. void* thr1_func(void* arg)
    15. {
    16.     int fd2 = open("thr2.out", O_CREAT | O_WRONLY, 0660);
    17.     printf("fd=%u, err=%s\n",fd2, strerror(errno));
    18.     int mq;
    19.     if ((mq = msgget(80, IPC_CREAT | IPC_EXCL | 0660)) == -1)
    20.     {
    21.         if (errno != EEXIST)
    22.         {
    23.             perror("msgget()");
    24.             return (void*)-1;
    25.         }
    26.         mq = msgget(80, 0);
    27.     }
    28.     printf("mq2=%u\n", mq);
    29.     msgbuff mb = {0, 0};
    30.     while (mb.data != '!')
    31.     {
    32.         int r = msgrcv(mq, &mb, sizeof mb, 81, 0);
    33.         //printf("r=%u d=%c, ", r, mb.data);
    34.         int a=write(fd2, &mb.data, 1);
    35.         printf("fd=%d, ", /*r, mb.data, */fd2);
    36.     }
    37.     printf("222\n");
    38.     printf("fd=%d", fd2);
    39.     int r=close(fd2);
    40.     printf("r=%d err=%s\n", r, strerror(errno));
    41.     return NULL;
    42. }
    43.  
    44. int main()
    45. {
    46.     pthread_t thr1;
    47.     pthread_create(&thr1, NULL, thr1_func, NULL);
    48.     int mq;
    49.     if ((mq = msgget(80, IPC_CREAT | IPC_EXCL | 0660)) == -1)
    50.     {
    51.         if (errno != EEXIST)
    52.         {
    53.             perror("msgget()");
    54.             return -1;
    55.         }
    56.         mq = msgget(80, 0);
    57.     }
    58.     printf("mq1=%u\n", mq);
    59.     int fd = open("thr2.cpp", O_RDONLY, 0660);
    60.     char c;
    61.     struct msgbuff mb;
    62.     while (read(fd, &c, 1) != 0)
    63.     {
    64.         //printf("%c", c);
    65.         printf("fd1=%d",fd);
    66.         if (c == 'e' || c == 'y' || c == 'u' || c == 'i' || c == 'o' || c == 'a')
    67.         {
    68.             mb.mtype = 81;
    69.             mb.data = c;
    70.             msgsnd(mq, &mb, sizeof mb, 0);
    71.         }
    72.     }
    73.     mb.mtype = 81;
    74.     mb.data = '!';
    75.     msgsnd(mq, &mb, sizeof mb, 0);
    76.     pthread_join(thr1, NULL);
    77.     printf("111 fd=%d\n", fd);
    78.     msgctl(mq, IPC_RMID, NULL);
    79.     close(fd);
    80.     return 0;
    81. }
    в конце main() стоит ожидание треда. интересно, что сначала выполняется весь main(), и только потом тред. почему не переключаются потоки?
    и ещё проблема: fd2 в треде меняется САМ. лог:
    Код (Text):
    1. [user@pluton-linux os]$ ./thr2
    2. mq1=524288
    3. fd1=3fd1=3fd1=3fd1=3 ... fd1=3fd1=3fd1=3fd=5, err=Success
    4. mq2=524288
    5. 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
    6. fd=184043748r=-1 err=Bad file descriptor
    7. 111 fd=3
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    потому что так реализовано создание процессов через clone()
    вновь созданный процесс переходит в состояние TASK_RUNNING и помещается в текущую очередь выполнения (если нет привязки к определенному логическому процессору) в одну из очередей ожидающих выполнения процессов согласно его приоритету
     
  10. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    rei3er, как я понимаю, логика потоков в том, что они выполняются в одном адресном пространстве «параллельно», то есть по маленьким кусочкам времени. как их заставить так работать?
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    они так иработают
     
  12. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    прога показывает, что они работают последовательно
     
  13. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    видимый эффект последовательности может быть, но на самом деле это не так
    вот пример
    Код (Text):
    1. static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    2.  
    3. static void print(const char * str) {
    4.     pthread_mutex_lock(&mutex);
    5.     puts(str);
    6.     pthread_mutex_unlock(&mutex);
    7. }
    8.  
    9. static void * routine(void * arg) {
    10.     while (1)
    11.         print("thread");
    12. }
    13.  
    14. int main() {
    15.     pthread_t thread;
    16.     pthread_create(&thread, NULL, &routine, NULL);
    17.     while (1)
    18.         puts("main");
    19.     return 0;
    20. }
     
  14. pluton

    pluton New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2007
    Сообщения:
    66
    Адрес:
    Odessa
    rei3er, я с этой прогой мучаюсь уже неделю. мне всегото надо в одном треде считать инфу, в другом записать только гласные. я уже запутался, пробовал с семафорами и сообщениями.
    даже на винде написал с семафорами, так там тоже глюки, символы пропадают