#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);
}
переключение потоков в Linux
Программа создающая два потока написана (задача производителя-потребителя), проблема в том, как измерить время переключения.
Известно что есть 4 способа, но в голову абсолютно ничего адекватного не приходит.
Пыталась посчитать время с помощью функции gettimeofday, путем вычитания из времени начала потока потребителя время окончания потока производителя и наоборот, но в итоге получаются отрицательные числа, причем совешенно разные каждый раз (от десятков мкс до десятых долей секунды)
Думаю, что это из-за того что не там фиксирую время.
Помогите пожалуйста разобраться
нет, не получается, так что придется тебе выкладывать код, показывать где, что, как и когда делаешь. без кода то мы помочь не сможем, а телепатия сегодня чего то плохо работает!
Вот код программы (задача производитель-потребитель):
Ну или так:
во вторых, не вижу где и как ты замеряешь время переключения, так что замеры в студию.
Заменила и офрмила код.
Код:
int tpcp= startc.tv_sec * 1000000 + startc.tv_usec - endp.tv_usec - endptv_sec * 1000000;
ps: я полагаю, что tv_usec это микросекунды, то есть 10e-6 секунд.
и прибавлять к ним микросекунды?
Код:
time_t tv_sec; /* Секунды */
suseconds_t tv_usec; /* Микросекунды */
suseconds_t tv_usec; /* Микросекунды */
Функция gettimeofday() записывает текущее время, выраженное в секундах и микросекундах от начала отсчета, в структуру типа timeval
Цитата: Artem_3A
делай так:
Код:
int tpcp= startc.tv_sec * 1000000 + startc.tv_usec - endp.tv_usec - endptv_sec * 1000000;
Попыталась использовать это предложение, не очень вышло, значения все чередуются то отрицательные, то положительные.
прилагаю скрин работы программы:
Цитата: racushka
А зачем секунды умножать на 1000000?
и прибавлять к ним микросекунды?
и прибавлять к ним микросекунды?
тем самым мы вычисляем прошедшее время в микросекундах.
относительно второго поста, я вообще не пользовался особо позиковским апи работы со временем, но кажись ты не верно понимаешь выражение
Цитата:
Функция gettimeofday() записывает текущее время, выраженное в секундах и микросекундах от начала отсчета, в структуру типа timeval
тут я полагаю имеется в виду не то, что время дублируется в секундах и микросекундах, а то что время представлено как совокупность прошедших секунд и микросекунд с последней секунды.
Может есть идеи как можно это по другому сделать, я просто даже теоретически не очень понимаю как это можно реализовать, преподаватель сказал, что есть 4 варианта, но не один не назвал... Осталась последнюю лабу защитить (это и есть защита) и сессия открыта... а тут такое... Эх... Или может есть какая литература полезная, или ссылки?
стандартные функции работы со временем С.
а так же на мысли наводит, что ты замеряешь время в цикле, может мерять по его завершении? еще интересно смотрятся слипы в секундах и случайный услип.
попробуй использовать
а так же на мысли наводит, что ты замеряешь время в цикле, может мерять по его завершении? еще интересно смотрятся слипы в секундах и случайный услип.
http://www.cplusplus.com/reference/clibrary/ctime/clock/
примерчик набросал...
правда я Си не сильно люблю, поэтому юзал вывод плюсовский... но заменить cout на print не проблема
п.с. т.е. замерить clock() при запуске потоков и потом ждать в цикле завершения обоих потоков...
что то типа(код примерный):
а может через 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;
}
#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();
}
...
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();
}
ну эт изврат уже. если так идти то помниться в асме есть специальная команда в х86 для запуска счетчика!:):):)
Цитата: Artem_3A
ну эт изврат уже. если так идти то помниться в асме есть специальная команда в х86 для запуска счетчика!:):):)
надо посчитать?)) ну вот я и посчитал))
а то что изврат... зато особо не нужно с кодом думать... тут же лабу надо сдать, а не искать элегантное решение:D
Спасибо сегодня попробую так сделать