Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: StatuS74 от Сентябрь 05, 2011, 06:26



Название: потоки перемешались
Отправлено: StatuS74 от Сентябрь 05, 2011, 06:26
сделал программу по тестированию датчиков. и столкнулся с такой штукой что  вовремя тест на одном из этапов когда один поток закончил работу. а второй  потом(2 датчик) перешел к последнему тесту то данные теста он берет не  свои а того датчика который до него был и начинает тестирование (продолжает) предыдущего датчика. не могу понять почему...

 вот часть когда для 2-х датчиков
Код:
 {switch (chet_dat)
        {
       case 1:
           {
               QString file_name1 = "datchic1.txt";
               test * t = new test();
               t->full_test(file_name1,nms,ftHandle1,serial1_1,
                           tn1_1,tk1_1,Tyd1_1);
               t->start();

               break;
           }
       case 2:
           {
               QString file_name2 = "datchic2.txt";
               test * t2 = new test();
               t2->full_test(file_name2,nms,ftHandle1,serial2,
                           tn2,tk2,Tyd2);
               t2->start();
               break;

           }
........


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 05, 2011, 08:11
Что делает метод test::full_test() и какие у него параметры?
nms,ftHandle1 и там, и там должны быть одинаковыми?
код самого теста бы увидеть.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 05, 2011, 08:36
Код:
void test::full_test( QString file_name,QString nms,FT_HANDLE ftHandle1,QString serial,double tna,double tk,int time_okonch )
{
       file_name_=file_name;
        nms_=nms;
        ftHandle1_=ftHandle1;
        serial_=serial;
        tna_=tna;
        tk_=tk;
        time_okonch_=time_okonch;
}


потом я запускаю run

Код:
 void test::run()
    {
          bool fl=false;
          connect(this, SIGNAL(signal_win(QString)),SLOT(mysignal_win(QString)));
          connect(this, SIGNAL(signal_fail1(QString)),SLOT(mysignal_fail1(QString)));
          connect(this, SIGNAL(signal_fail2(QString)),SLOT(mysignal_fail2(QString)));
           fl=test::tempiratura_datchika(tna_,file_name_,nms_,ftHandle1_,serial_);
           if (fl == true)
           { int grad =0;
              grad = test::Start_test(tk_,file_name_,nms_,ftHandle1_,serial_);
              if (grad>=tk_-0.5)
              {  bool  time_full = false;
                 time_full = test::time_test_2(time_okonch_,file_name_,ftHandle1_,serial_);
                          if (time_full == true)
                  {
                            emit signal_win(serial_);

                  }
                    else
                 {
                     emit signal_fail2(serial_);
                 }
              }
              else
              {
                  emit signal_fail1(serial_);


              }}
           else
           {
                emit signal_fail1(serial_);

           }

    }




Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 05, 2011, 08:50
получается тут следующее начинается тест (тестирую на параллельно 2-х прибора). проходят тест 1,2. потом например 1 датчик быстрее прошел первые 2 теста проходит 3 тест заканчивает его. второй датчик тока подошел к 3 тесту и запускается тест с аргументами того датчика который прошел уже тест


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 05, 2011, 13:02
nms,ftHandle1 одинаковые. нмс это номер сообщения  которое отправляется в командой в прогроматор а фтхендел это грубо говоря айди контроллера в прогроматоре


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 06, 2011, 06:01
проблему так и не решил.. подскажите что может быть ?


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 06, 2011, 08:59
Методы test::tempiratura_datchika, test::Start_test,test::time_test_2 зачем сделаны статическими?


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 06, 2011, 13:04
ну я решил что так будет правильней.


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 06, 2011, 13:31
Члены класса, с которыми работают методы, случаем не статические?


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 06, 2011, 13:37
не не статические.
вот методы класса
Код:
   static int Start_test(double,QString,QString,FT_HANDLE,QString);
    static bool tempiratura_datchika (double,QString ,QString ,FT_HANDLE ,QString);
    static QString Serialnum (const QString &serial);
    static bool time_test_2(int,QString,FT_HANDLE,QString);
    static void full_test( QString,QString,FT_HANDLE,QString,double,double,int);
    static double preobrazovanie(QString);
    void run();



Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 06, 2011, 13:54
Что-то я не въеду, где потоки могу к одной и той же информации обратится.
Попробуй переделать статические методы в обычные. Если не поможет смотри в каком месте и в какой момент данные меняются.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 06, 2011, 13:56
они обращаются к одним и темже функциям в классе ран. собственно то что я в поток и запускаю.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 06, 2011, 14:24
сделать обычный метод не статический не помогло...


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 06, 2011, 15:36
Я сдаюсь, ты победил... :)

Ты уверен, что нет данных в которые может писать и первый поток и второй? В третьем тесте используются: time_okonch_,file_name_,ftHandle1_,serial_ - все они члена класса test, и если они не объявлены статическими, то из одного экземпляра в другой доступа не должно быть.

Объявление класса test и реализацию test::time_test_2 в студию.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 05:58
вчера переписал этот метод теперь он выглядит так

Код:
int test::time_test_2(int time_okonch,QString file_name,FT_HANDLE ftHandle1,QString serial,int tes)
    {
        mutex1.lock();
       QString nms = "0";
       QTime time_konca;
       int vremia_t=tes;
       time_okonch=(time_okonch)*1000;
       time_konca.start();
          nms= test::ReadWrite(serial,nms,file_name,ftHandle1);
           vremia_t=time_konca.elapsed();
           mutex1.unlock();
          return vremia_t/1000;
      }

метод run стал выглядить так

Код:
 bool fl=false;
          int grad =0;

          int t3=0;
          connect(this, SIGNAL(signal_win(QString)),SLOT(mysignal_win(QString)));
          connect(this, SIGNAL(signal_fail1(QString)),SLOT(mysignal_fail1(QString)));
          connect(this, SIGNAL(signal_fail2(QString)),SLOT(mysignal_fail2(QString)));
           fl=test::tempiratura_datchika(tna_,file_name_,nms_,ftHandle1_,serial_);
           if (fl == true)
           {  grad = test::Start_test(tk_,file_name_,nms_,ftHandle1_,serial_);
              if (grad>=tk_-0.5)
              {

                 t3 = test::time_test_2(time_okonch_,file_name_,ftHandle1_,serial_,t3);
                 while(t3<=time_okonch_)
                   {

                     t3 = test::time_test_2(time_okonch_,file_name_,ftHandle1_,serial_,t3);


                 }
                 if(t3>=time_okonch_)
                  {
                            emit signal_win(serial_);

                        }
                    else
                 {
                     emit signal_fail2(serial_);
                 }
                }

              else
              {
                  emit signal_fail1(serial_);

              }}
           else
           {
                emit signal_fail1(serial_);

           }

    }


запускаю поток вот так

Код:
 {switch (chet_dat)
        {
       case 1:
           {
               QString file_name1 = "datchic1.txt";
               test * t = new test();
               t->full_test(file_name1,nms,ftHandle1,serial1_1,
                           tn1_1,tk1_1,Tyd1_1);
               t->start();

               break;
           }
       case 2:
           {
               QString file_name2 = "datchic2.txt";
               test * t2 = new test();
               t2->full_test(file_name2,nms,ftHandle1,serial2,
                           tn2,tk2,Tyd2);
               t2->start();


               break;
и тд для 12 датчиков

           }


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 07, 2011, 08:10
Если хочешь использовать QMutex, надо чтобы все экземпляры класса test обращались к одному и тому же экземпляру QMutex. Сделай его глобальным или статическим членом класса test.

Код:
class test: public QThread /*, ...*/
{
  /*...*/
  private static QMutex mutex1;
  /*...*/
}

int test::time_test_2(int time_okonch,QString file_name,FT_HANDLE ftHandle1,QString serial,int tes)
{
  /*...*/
  test::mutex1.lock();
  /*...*/
  test::mutex1.unlock();
  /*...*/
}


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 08:15
а что мне это даст если они будут к одному обращаться ?


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 08:18
вроде забулькало.. теперь не пому почему после того как тест 3 закончился. происходит
Код:
 t3 = test::time_test_2(time_okonch_,file_name_,ftHandle1_,serial_,t3);
                if (t3==true)
                 {
                    emit mysignal_win(serial_);
                   
                 }
и после  emit валится программа.  пробывал и просто меседж вместо него написать тоже валится..


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 07, 2011, 10:30
а что мне это даст если они будут к одному обращаться ?
Когда один из потоков вызывает lock(), он захватывает данные и другие потоки не могу к этим данным обратится и будут ждать, когда данные освободятся. А если мьютексы будут разные, то каждый поток залочит свой экземпляр мьютекса и доступ к данным останется.

вроде забулькало.. теперь не пому почему после того как тест 3 закончился. происходит
...
и после  emit валится программа.  пробывал и просто меседж вместо него написать тоже валится..
Постом ниже было вроде так =)
Код:
int t3=0;
/*...*/
while(t3<=time_okonch_)
{
  t3 = test::time_test_2(time_okonch_,file_name_,ftHandle1_,serial_,t3);
}
if(t3>=time_okonch_)
{
  emit signal_win(serial_);
}
else
{
  emit signal_fail2(serial_);
}
/*...*/
Падает при или после emit? Может объект-приемник инвалидный?

По сути: если с мьютексами заработало, то где-то между lock() и unlock() у тебя используются общие данные, это может быть: глобальные переменные или статические члены.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 10:42
падает на emit. щас разбираюсь.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 10:53
пробую и просто
 QMessageBox::warning(0,"ГОТОВО",
                              "Тестирование завершено для датчика с серийным номером  "
                                                                 +serial,
                                                                  QMessageBox::Ok,QMessageBox::Ok);

всеравно падает.. что то я даже не знаю на что подумать...


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 07, 2011, 10:58
Вызов QMessageBox возможен только в GUI-потоке, в других потоках вызвать не получится.

если без emit просто qDebug()<<"complete"; вызвать тоже падает?


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 11:13
нет не падает. так сигнла тоже не катит ??? а как тогда мне вывести сообщение ?


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 13:25
эх... так и не нашол ответа как вывисти сообщение из потока =(


Название: Re: потоки перемешались
Отправлено: LisandreL от Сентябрь 07, 2011, 13:39
так и не нашол ответа как вывисти сообщение из потока
Для себя - qDebug и смотреть в консоли. Для пользователя - можно испускать сигнал с текстом сообщения-параметром, в гуёвом потке ловить слотом и показывать сообщение.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 13:44
а как в гуевый поток отправить сигнал ? дебагом я ловлю. у меня проект встал на месте что бы отображать пользователю.


Название: Re: потоки перемешались
Отправлено: LisandreL от Сентябрь 07, 2011, 14:07
а как в гуевый поток отправить сигнал?
Как и любой другой - emit'ом.
Принимающий объект должен быть создан в гуёвом потоке. Тип коннекта не Qt::DirectConnection.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 14:17
ну все сообщение выводится тока номер серийника ни тот который должен. а последний..


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 07, 2011, 15:18
все равно на 3 тесте берет параметры последнего теста


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 07, 2011, 16:19
i
Код:
nt test::time_test_2(int time_okonch,QString file_name,FT_HANDLE ftHandle1,QString serial,int tes)
    {
        mutex1.lock();
       QString nms = "0";
       QTime time_konca;
       int vremia_t=tes;
       time_okonch=(time_okonch)*1000;
       time_konca.start();
          nms= test::ReadWrite(serial,nms,file_name,ftHandle1);
           vremia_t=time_konca.elapsed();
           mutex1.unlock();
          return vremia_t/1000;
      }

mutex1.lock(); и mutex1.unlock(); где-то изменяется глобальная переменная или статический элемент, отсюда и неправильные данные для теста и серийный номер. Методом исключения - в ReadWrite(serial,nms,file_name,ftHandle1);


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 08, 2011, 05:55
mutex1.lock(); и mutex1.unlock() я использую тока 1 раз. она объявлена как глобальная переменная


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 08, 2011, 06:09
они изменяются тока в методе test_full. то есть я в этот метод отправляю переменные которые необходимы мне для тестирования. присваиваю их глобальным переменным класса и отправляю в поток.


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 08, 2011, 06:24
а может ли быть из за того что я для каждой кнопка а их у меня 12 создаю свой экземпляр класса. и потом запускаю поток ?


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 08, 2011, 07:19
попробывал через один все равно таже фигня


Название: Re: потоки перемешались
Отправлено: shirushizo от Сентябрь 08, 2011, 08:31
они изменяются тока в методе test_full. то есть я в этот метод отправляю переменные которые необходимы мне для тестирования. присваиваю их глобальным переменным класса и отправляю в поток.
что значит "глобальным переменным класса" ?

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


Название: Re: потоки перемешались
Отправлено: StatuS74 от Сентябрь 08, 2011, 08:53
решил сделать по тупому и как обычно все заработало. в окончании теста 2 перед тем как возвратить значение тру что бы перейти к 3 тесту  присваиваю переменным которые в фул тест значения того тесто который начинает проходить 3 тест.. и все забулькало... дргого варианта решения проблемы не нашел