Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

переключение потоков в Linux

58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Нужно написать программу создающую 2 параллельных потока и измерить время переключения этих потоков.
Программа создающая два потока написана (задача производителя-потребителя), проблема в том, как измерить время переключения.

Известно что есть 4 способа, но в голову абсолютно ничего адекватного не приходит.
Пыталась посчитать время с помощью функции gettimeofday, путем вычитания из времени начала потока потребителя время окончания потока производителя и наоборот, но в итоге получаются отрицательные числа, причем совешенно разные каждый раз (от десятков мкс до десятых долей секунды)
Думаю, что это из-за того что не там фиксирую время.
Помогите пожалуйста разобраться
307
23 мая 2010 года
Artem_3A
863 / / 11.04.2008
попытка телепатического соединения с кодом... сбой... ожидание... соединение... сбой... ожидание... соединение... сбой... соединение не удалось.

нет, не получается, так что придется тебе выкладывать код, показывать где, что, как и когда делаешь. без кода то мы помочь не сможем, а телепатия сегодня чего то плохо работает!
58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Вот код программы (задача производитель-потребитель):
58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Ну или так:
Код:
#include <pthread.h>
#include <stdio.h>
 
#include <stdlib.h>
struct timeval startp/*время начала потока производителя*/,
                   endp/*время окончания потока производителя*/,
                   startc/*время начала потока потребителя*/,
                   endc /*время окончания потока потребителя*/;
pthread_cond_t k;
pthread_mutex_t sync;
int BF[10];
int num=0, prod_num=1, cons_num=1, i=0, t, tpcp/*время переключения потребитель-производитель*/,tppc/*время переключения производитель-потребитель*/;
void *produser()
{
 while(1)
  { gettimeofday(&startp, NULL);
    pthread_mutex_lock(&sync);//захват мьютекса
 
    while(num==10)
     {
      pthread_cond_wait(&k, &sync);//блокировка вызывающего потока
          sleep(1);
      gettimeofday(&endp, NULL);
      int tpcp=startc.tv_usec-endp.tv_usec;
      printf("Время переключения cp при блокировке: %d\n", tpcp);
     }
    BF[prod_num]=i%10;
    i++;
    num++;
    printf("     Запись символа %d", BF[prod_num]);
    printf("     количество символов в буфере%d\n",num);  
    prod_num=(prod_num+1)%10;
    pthread_cond_signal(&k);//будит поток
    pthread_mutex_unlock(&sync);//освобожение мьютекса
    sleep(1);
    gettimeofday(&endp, NULL);
    int tpcp=startc.tv_usec-endp.tv_usec;
    printf("Время переключения cp: %d\n", tpcp);
    t=(rand()%1500000+500000);
    usleep(t);
    //printf("     Ожидание чтения%d\n",t);
    if(num==9)
       sleep(2);
 
  }
 return;
}
void *consumer()
{
 while(1)
  { gettimeofday(&startc, NULL);
    pthread_mutex_lock(&sync);
 
    while(num==0)
     {
      pthread_cond_wait(&k, &sync);
      sleep(1);
      gettimeofday(&endc, NULL);
      int tppc=startp.tv_usec-endc.tv_usec;
      printf("Время переключения pc при блокировке: %d\n", tppc);
     }
    num--;
    printf("     Чтение символа %d", BF[cons_num]);
    printf("     количество символов в буфере%d\n",num);
    cons_num=(cons_num+1)%10;
    pthread_cond_signal(&k);
    pthread_mutex_unlock(&sync);
    sleep(1);
    gettimeofday(&endc, NULL);
    int tppc=startp.tv_usec-endc.tv_usec;
    printf("Время переключения pc: %d\n", tppc);
    t=(rand()%1500000+500000);
    usleep(t);
    //printf("     Ожидание записи%d\n",t);
 
  }
 return;
}
main()
{
 pthread_t thread_prod, thread_cons;//идентификаторы потоков
 pthread_cond_init(&k,NULL);//k - идентификатор условной переменой
 pthread_mutex_init(&sync,NULL);//создание мьютекса
 pthread_create(&thread_prod,NULL,produser,NULL);//создание потока производителя
 pthread_create(&thread_cons,NULL,consumer,NULL);//создание потока потребителя
 pthread_join(thread_prod,NULL);//блокирует поток потребителя до тех пор, пока не завершит свою работу поток производителя
 pthread_join(thread_cons,NULL);
}
307
23 мая 2010 года
Artem_3A
863 / / 11.04.2008
во первых, оформи код тегами, бо читать невозможно, как это сделать см. мою подпись.
во вторых, не вижу где и как ты замеряешь время переключения, так что замеры в студию.
58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Заменила и офрмила код.
307
23 мая 2010 года
Artem_3A
863 / / 11.04.2008
а если переключение было дольше секунды, минуты? вот от сюда и получается отрицательно время. делай так:

 
Код:
int tpcp= startc.tv_sec * 1000000 + startc.tv_usec - endp.tv_usec - endptv_sec * 1000000;


ps: я полагаю, что tv_usec это микросекунды, то есть 10e-6 секунд.
58K
23 мая 2010 года
racushka
10 / / 23.05.2010
А зачем секунды умножать на 1000000?
и прибавлять к ним микросекунды?
58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Согласно стандарту POSIX-2001, описанная в заголовочном файле <sys/time.h> структура timeval содержит по крайней мере следующие поля.
 
Код:
time_t      tv_sec;     /* Секунды */
suseconds_t tv_usec;    /* Микросекунды */

Функция gettimeofday() записывает текущее время, выраженное в секундах и микросекундах от начала отсчета, в структуру типа timeval
58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Цитата: Artem_3A
делай так:

 
Код:
int tpcp= startc.tv_sec * 1000000 + startc.tv_usec - endp.tv_usec - endptv_sec * 1000000;



Попыталась использовать это предложение, не очень вышло, значения все чередуются то отрицательные, то положительные.
прилагаю скрин работы программы:

307
23 мая 2010 года
Artem_3A
863 / / 11.04.2008
Цитата: racushka
А зачем секунды умножать на 1000000?
и прибавлять к ним микросекунды?



тем самым мы вычисляем прошедшее время в микросекундах.

относительно второго поста, я вообще не пользовался особо позиковским апи работы со временем, но кажись ты не верно понимаешь выражение

Цитата:
Функция gettimeofday() записывает текущее время, выраженное в секундах и микросекундах от начала отсчета, в структуру типа timeval



тут я полагаю имеется в виду не то, что время дублируется в секундах и микросекундах, а то что время представлено как совокупность прошедших секунд и микросекунд с последней секунды.

58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Может есть идеи как можно это по другому сделать, я просто даже теоретически не очень понимаю как это можно реализовать, преподаватель сказал, что есть 4 варианта, но не один не назвал... Осталась последнюю лабу защитить (это и есть защита) и сессия открыта... а тут такое... Эх... Или может есть какая литература полезная, или ссылки?
307
23 мая 2010 года
Artem_3A
863 / / 11.04.2008
попробуй использовать стандартные функции работы со временем С.

а так же на мысли наводит, что ты замеряешь время в цикле, может мерять по его завершении? еще интересно смотрятся слипы в секундах и случайный услип.
2.1K
23 мая 2010 года
Norgat
452 / / 12.08.2009
а может через clock() сделать это?http://www.cplusplus.com/reference/clibrary/ctime/clock/

примерчик набросал...

Код:
#include <pthread.h>
#include <iostream>
#include <time.h>

using namespace std;

bool thread1_flag = false;

void* thread1(void*)
{
    cout << "start thread1 clock(): " << clock() << endl;
    timespec sec;
    sec.tv_sec = 0;
    sec.tv_nsec = 100000000;  
    nanosleep(&sec,NULL);
    thread1_flag = true;
    cout << "end thread1 clock(): " << clock() << endl ;
}

int main()
{
    cout << "start program clock(): " << clock() << endl;
    pthread_t hthread;
    pthread_create(&hthread,NULL,thread1,NULL);
    while(thread1_flag == false);
    cout << "end program clock(): " << clock() << endl;

    return 0;
}


правда я Си не сильно люблю, поэтому юзал вывод плюсовский... но заменить cout на print не проблема

п.с. т.е. замерить clock() при запуске потоков и потом ждать в цикле завершения обоих потоков...
что то типа(код примерный):
Код:
bool thread1_flag = false, thread2_flag = false;
...
int start_thread1 = clock();
pthread_create(1й поток);
...
int start_thread2 = clock();
pthread_create(2й поток);
...
int end_thread1 = 0, end_thread2 = 0;
while(end_thread1 == 0 || end_thread2 == 0)
{
    if(end_thread1 == 0 && thread1_flag == true) end_thread1 = clock();
    if(end_thread2 == 0 && thread2_flag == true) end_thread2 = clock();
}
307
23 мая 2010 года
Artem_3A
863 / / 11.04.2008
ну эт изврат уже. если так идти то помниться в асме есть специальная команда в х86 для запуска счетчика!:):):)
2.1K
23 мая 2010 года
Norgat
452 / / 12.08.2009
Цитата: Artem_3A
ну эт изврат уже. если так идти то помниться в асме есть специальная команда в х86 для запуска счетчика!:):):)



надо посчитать?)) ну вот я и посчитал))
а то что изврат... зато особо не нужно с кодом думать... тут же лабу надо сдать, а не искать элегантное решение:D

58K
23 мая 2010 года
racushka
10 / / 23.05.2010
Спасибо сегодня попробую так сделать
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог