The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Как заставить потоки выполняться последовательно?"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Как заставить потоки выполняться последовательно?"
Сообщение от aiboman emailИскать по авторуВ закладки(ok) on 03-Дек-04, 12:27  (MSK)
В ф-ции main я создаю 2 потока: print_xs1 и print_xs2.
print_xs1 записывает в массив arr последовательные значения.
print_xs2 считывает этот массив и выводит их на консоль.
Потоки используют мьютекс для разделения времени захвата массива.
По идее, потоки должны выполняться последовательно, но вывод программы
наводит меня на мысль, что это не так. Результат: 4545454545 (много раз), потом 67, потом 78 (оч. много раз), хотя я ожидаю:
0123456789 (оч. много раз)... Что я неправильно делаю?

Код программы:
----------------------------------------------
my_threads.c
----------------------------------------------
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>

int arr[2];
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

void* print_xs1 (void* unused)
{
int i=0;
while (1)
{
pthread_mutex_lock(&mutex);
    arr[0]=i;
    arr[1]=i+1;
    i+=2;
    if (i>9) i=0;
pthread_mutex_unlock(&mutex);
}
return NULL;
}

void* print_xs2 (void* unused)
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("%d",arr[0]);
printf("%d",arr[1]);
pthread_mutex_unlock(&mutex);
}
return NULL;
}

int main()
{
pthread_t thread_id1;
pthread_t thread_id2;

pthread_create(&thread_id1, NULL, &print_xs1, NULL);
pthread_create(&thread_id2, NULL, &print_xs2, NULL);

while (1)
{

}
return 0;
}

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Как заставить потоки выполняться последовательно?"
Сообщение от gyn61 Искать по авторуВ закладки(ok) on 03-Дек-04, 12:50  (MSK)
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>

int arr[2];
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
int array_is_full = 0;

void* print_xs1 (void* unused)
{
int i=0;
while (1)
{
  pthread_mutex_lock(&mutex);
    if (!array_is_full)
    {
     arr[0]=i;
     arr[1]=i+1;
     i+=2;
     if (i>9) i=0;
     array_is_full=1;
    }
pthread_mutex_unlock(&mutex);
}
return NULL;
}

void* print_xs2 (void* unused)
{
while (1)
{
pthread_mutex_lock(&mutex);
  if (array_is_full)
  {
    printf("%d",arr[0]);
    printf("%d",arr[1]);
    array_is_full=0;
  }
pthread_mutex_unlock(&mutex);
}
return NULL;
}

int main()
{
pthread_t thread_id1;
pthread_t thread_id2;

pthread_create(&thread_id1, NULL, &print_xs1, NULL);
pthread_create(&thread_id2, NULL, &print_xs2, NULL);

while (1)
  {

  }
return 0;
}


  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Как заставить потоки выполняться последовательно?"
Сообщение от aiboman emailИскать по авторуВ закладки(ok) on 03-Дек-04, 13:21  (MSK)
Спасибо, gyn61. Я использовал указанный Вами метод, это действительно помогает - потоки синхронизируются, однако происходит это довольно странно: программа при выполнении "задумывается" секунд на 15, и только после этого выводит порцию "много раз по 0123456789" (после этого опять впадает в спячку). Кстати говоря, при использовании доп.переменной можно обойтись вовсе без мьютекса - результат будет тот же (правильный, но с тормозами). Система SuSE Linux 9.0
  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Как заставить потоки выполняться последовательно?"
Сообщение от Pablo Искать по авторуВ закладки on 03-Дек-04, 13:42  (MSK)
>Спасибо, gyn61. Я использовал указанный Вами метод, это действительно помогает - потоки
>синхронизируются, однако происходит это довольно странно: программа при выполнении "задумывается" секунд
>на 15, и только после этого выводит порцию "много раз по
>0123456789" (после этого опять впадает в спячку). Кстати говоря, при использовании
>доп.переменной можно обойтись вовсе без мьютекса - результат будет тот же
>(правильный, но с тормозами). Система SuSE Linux 9.0

Попробуй так.
---------------------------------------------------
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>

int arr[2];
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
int array_is_full = 0;
pthread_cond_t is_full =PTHREAD_COND_INITIALIZER;
pthread_cond_t not_full =PTHREAD_COND_INITIALIZER;

void* print_xs1 (void* unused)
{
int i=0;
while (1)
{
  pthread_mutex_lock(&mutex);
    while (array_is_full) {
        pthread_cond_wait (¬_full, &mutex);
    }
     arr[0]=i;
     arr[1]=i+1;
     i+=2;
     if (i>9) i=0;
     array_is_full=1;
   pthread_cond_signal (&is_full);
pthread_mutex_unlock(&mutex);
}
return NULL;
}

void* print_xs2 (void* unused)
{
while (1)
{
pthread_mutex_lock(&mutex);
    while (!array_is_full) {
        pthread_cond_wait (&is_full, &mutex);
    }
    printf("%d",arr[0]);
    printf("%d",arr[1]);
    array_is_full=0;
   pthread_cond_signal (¬_full);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
........
и т.д.
--------------

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "Как заставить потоки выполняться последовательно?"
Сообщение от aiboman emailИскать по авторуВ закладки(ok) on 03-Дек-04, 14:21  (MSK)
Большое спасибо, Pablo. Похоже, это то, что нужно. Результат запуска программы отпишу из дома (linux-система стоит именно там).
Кстати, pthread_cond_signal (¬_full) =  pthread_cond_signal (&is_full) ?
  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "Как заставить потоки выполняться последовательно?"
Сообщение от Pablo Искать по авторуВ закладки on 03-Дек-04, 15:02  (MSK)
>Большое спасибо, Pablo. Похоже, это то, что нужно. Результат запуска программы отпишу
>из дома (linux-система стоит именно там).
>Кстати, pthread_cond_signal (¬_full) =  pthread_cond_signal (&is_full) ?

Нет, просто (& not_full) без пробела неправильно транслировалось

Хотя в таком простом примере который ты привел,
с одним потоком производителем и одним потоком потребителем,
можно обойтись только одной условной переменной,
и заменить все not_full на is_full  

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Как заставить потоки выполняться последовательно?"
Сообщение от aiboman Искать по авторуВ закладки(ok) on 06-Дек-04, 11:04  (MSK)
Попробовал с одной сигнальной переменной -
Pablo, это действительно работает! Еще раз большое спасибо :)


  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру