Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Останавливается поток когда вкл-откл отображение ярлыков раб стола

Привет всем! Помогите разобраться не как не могу решить проблему.
Есть код при старте окна запуск потока
Potok:=TPotok.Create(False);
Potok.Priority:=tpNormal;

в потоке начало
Potok.FreeOnTerminate:=True;
затем поучение json с сети запись данных в лейбы
конец потока запуск процедуры в которой
Potok.Terminate;
Potok:=TPotok.Create(False);
Potok.Priority:=tpNormal;

и так постоянно...

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

Так же если зайти на комп через тимвайвер и выйти , то он тоже остановится.

Пишу в CodeTyphon32 Windows 7 32bit
Ответ: Все победил спасибо ))))
Вопрос: Почему не останавливается поток?

C#
1
public Thread _ParsGrups ;
C#
1
2
3
4
  void star_or_stop(DevExpress.XtraBars.BarButtonItem e, DevExpress.XtraBars.BarButtonItem a,bool b, Thread c, ThreadStart n = null)
       {
          try { e.Enabled = true; a.Enabled = false; if(b) { c = new Thread(n); c.IsBackground = true; c.Start(); } else { c.Abort(); } } catch { }
       }
Запускаю поток
C#
1
2
3
4
 private void barButtonItem5_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
       {
         star_or_stop(barButtonItem6, barButtonItem5, true,_ParsGrups, pars_grups); }
       }
Останавливаю поток

C#
1
2
3
4
 private void barButtonItem6_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
       {
         star_or_stop(barButtonItem5, barButtonItem6, false, _ParsGrups);        
       }
Поток не останавливается, в чем проблема , помогите пожалуйста!
Ответ: Вопрос решен
Вопрос: Мистическое исчезновение потоков

Здравствуйте, гуру форума! Пишу программку, основанную на потоках и http/https запросах. Сейчас объясню в чём собственно проблема заключается..
Сначала создаётся глобальный массив из потоков:
Delphi
1
MyT : array[1..1000] of TMyThread;
Затем я запускаю эти потоки:
Delphi
1
2
3
4
5
6
7
8
9
  for i := 1 to n do
    begin
    MyT[i]:= TMyThread.create(true, i, mol[i].beg , mol[i].en, lo, pa);
    dec(mak[i].proverka);
    MyT[i].priority:= tpnormal;
    MyT[i].FreeOnTerminate:= true;
    MyT[i].start;
    wait(1);
    end;
n - это количество потоков, mol[i].beg и mol[i].en - начальное и конечное значение обрабатываемых данных из массива(чтобы потоки не пересекались, решил поставить такую логику. каждый поток работает со своей частью массива), lo и pa - это логин и пароль от проксиков(это уже не столь важно ), и через mak[i].proverka я проверяю завершился ли данный поток. start использую, потому что на resume делфи ругается, мол ненадёжный оператор.
Потоки запускаются, запускаются,по началу всё работает как часы:
Delphi
1
2
3
4
5
6
for plok := beg to en do
begin
r:= plok;
if not vremya(mak[r].time) then
begin
...
цикл от начала и до конца значений, заданных потоку. Массив mak[r].time тоже глобальный, хоть это и чтение, но всё равно потоки, по идее, не должны обращаться к одному и тому же значению массива одновременно.
функция vremya просто сравнивает значение времени в массиве с настоящим моментом и выдаёт true, если прошло меньше часа(не знаю почему, но переменные boolean в потоке не хотят принимать значение false, только через dec() ):
Delphi
1
2
3
4
5
6
7
8
function TMyThread.vremya(date: TdateTime): boolean;
var diff: double;
begin
result:= true;
diff:= now - date;
diff:= diff*24;
if diff>1 then dec(result);
end;
Итак, затем идёт долгое и нудное составление http запросов, try except, все дела, программа делает своё дело и изменяет время в массиве(естественно через synchronize(), хотя в принципе не знаю зачем он тут), в зависимости от ответа сервера. Вот пример:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
if pos('s1',sab)<>0 then
  begin
   synchronize(MemoAdd);
   number:=sab;
   Delete(number,1,pos(':',number));
   Delete(number,1,pos(':',number));
   Delete(number,1,pos(':',number));
   Delete(number,1,pos('.',number));
   Delete(number,pos(':',number),length(number));
   number:= inttostr(strtoint(number));
   synchronize(labl);
   synchronize(labl2);
  end
синхронизация в lable'ы для статистики и процедура MemoAdd вот:
Delphi
1
2
3
4
5
procedure TMyThread.MemoAdd;
begin
  mak[r].time:= now;
  Form1.memo1.lines.add('('+inttostr(r)+') '+TimeToStr(mak[r].time)+'...................................OK');
end;
Когда цикл закончился поток говорит, что закончил своё действие через переменную:
Delphi
1
mak[terminator].proverka:= true;
А с главного потока постоянно эта переменная проверяется:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
while work do
begin
for i := 1 to n do
  if mak[i].proverka then
  begin
  MyT[i]:= TMyThread.create(true,i, mol[i].beg, mol[i].en, lo, pa);
  dec(mak[i].proverka);
  MyT[i].priority:= tpnormal;
  MyT[i].FreeOnTerminate:= true;
  MyT[i].start;
  wait(1);
  end;
wait(5);
end;
Собственно проблема в том, что проработав часов 5 программа просто останавливается. Может не выполняется условие в потоке, может потоки не хотят запускаться, я не знаю. Не большие у меня познания в потоках, так что прошу помощи у вас
Если есть подозрения, что программа останавливается из-за внутренностей самого потока, то вряд ли, потому что, когда поток был только один, она работала на ура сутки напролёт и даже не подавала виду на крах.
На всякий случай вот создание и уничтожение всего нужного внутри потока:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  http1:= Tidhttp.Create(nil);
  cookie:= Tidcookiemanager.Create(nil);
  socksinfo:= Tidsocksinfo.Create(nil);
  socksinfo.Version:= svsocks5;
  socksinfo.Host:= mak[r].ip;
  socksinfo.port:= strtoint(mak[r].port);
  socksinfo.Authentication:= saUsernamePassword;
  socksinfo.Username:= login;
  socksinfo.Password:= pass;
  handler:= TIdSSLIOHandlerSocketOpenSSL.Create();
  http1.CookieManager:=cookie;
  handler.TransparentProxy:=socksinfo;
  http1.IOHandler:=handler;
  http1.AllowCookies:= true;
  p:= TStringList.Create;
  http1.HTTPOptions:=[hoKeepOrigProtocol,hoForceEncodeParams];
  http1.ConnectTimeout:= 5000;
  http1.ReadTimeout:= 5000;
Ну и безжалостное убийство:
Delphi
1
2
3
4
5
6
7
  p.Clear;
  http1.Request.Clear;
  http1.Request.CustomHeaders.Clear;
  cookie.CookieCollection.Clear;
  http1.Free;
  cookie.Free;
  socksinfo.Free;
Если есть добрые люди, которым не влом читать эту ахинею и знают как помочь, отзовитесь пожалуйста)

Добавлено через 8 минут
Единственное, что в однопоточной программе не было массива со временем, а вместо него был таймер. Но сейчас таймер не прокатит, ибо слишком большой объём информации и работа потоков не синхронна.
Ответ: на сколько я знаю tidantifreeze создан, чтобы форма не зависала
а выполнение, например, 15-ти http запросов в одном потоке, да и ещё одновременно кажется мне совсем нереальным)
Вопрос: Убийство потоков

C#
1
2
for (int j = 0; j < 10; j++)
                        Task.Factory.StartNew(() => Start());
Запускаем потоки так а останавливаем уже в самом потоке while(true/false) но меня это начало не устраивать останавливается очень долго. Какой есть вариант их убить через массив как то помню показывали. В массиве все потоки и потом убиваем и они останавливаются.

Добавлено через 4 часа 15 минут
UPp
Ответ:
Сообщение от Bo0m21
останавливается очень долго
Лучше пересмотрите код цикла.
Вопрос: Поток не останавливается после того, как вызывает метод

 public void run() {
    	flag = true;
    	while(!Thread.currentThread().isInterrupted() && flag){
    		prokladka();
    	}
    }
    
	private void prokladka(){
		try {
            Thread.sleep(10000);
            potok ();
    	
        } catch (InterruptedException e) {
        	System.out.println("Поток прерван");
            flag = false;
           
        }
	}


Если вызываю interrupt() в течении 10 секунд пока поток спит, поток прерывается. После 10 сек начинается продолжительная выборка из MySQL. И если в это время вызвать interrupt(), то поток не останавливается. Что надо сделать, чтобы он остановлся (прервался)?
Ответ:
avp.mk
Petro123
avp.mk,
Ну а про флаг и его видимость, то он вроди во всех потоковых наследниках есть из коробки.

Сергей_ТВ
public void run() {
flag = true;
while(!Thread.currentThread().isInterrupted() && flag){
prokladka();
}
}

private void prokladka(){
try {
Thread.sleep(10000);
potok ();

} catch (InterruptedException e) {
System.out.println("Поток прерван");
flag = false;

}
}

Поле, говорю, это не нужно и к тому же имеет дефект.



Да, флаг не к месту здесь. Он должен стоять за пределами run().
...
Понятно, что врядли кто стал проводить опыты по остановке длительной по времени выборки из MySQL. Поэтому напишу, что сделал.
В цикл чтения ResultSet добавил еще один флаг, а затем добавил условие для отмены стеймента

while (rs.next() && flagMySql ) {
      	                rs.getString(18);
               }
     
		if (!flagMySql) {
			stmt.cancel();
		}


Это стало работать. Причем после прерывания работы потока и остановки процесса выборки из MySQL, в консоле активность работы кода прекращалась. А после повторного вызова потока(с выборкой в том числе), выборка начиналась с начальных условий. Ошибок не наблюдал.
Вопрос: Разом уничтожить все потоки

Всем привет! Создаю несколько потоков таким образом:
C++
1
2
3
4
5
6
7
8
9
10
int i = 0;
    for (Form3->ADOQuery1->First(); !Form3->ADOQuery1->Eof; Form3->ADOQuery1->Next()){
        ArrayThread[i] = new SpyThread(ADOQuery1->FieldByName("SOURCE_DIRECTORY")->AsString, ADOQuery1->FieldByName("DESTINATION_DIRECTORY")->AsString, ADOQuery1->FieldByName("LID")->AsString);
 
        i++;
       }
       for(int n = 0; n<i; n++){
       ArrayThread[n]->Start();
       ArrayThread[n]->FreeOnTerminate = true;
       }
Вопрос: нигде ли я не ошибся?
И как мне потом разом убить все эти потоки?
Ответ:
Сообщение от volvo
Не совсем. Я бы попробовал добавить Sleep, чтобы снизить нагрузку на процессор. Кстати, сколько ядер у тебя, и сколько потоков создает приложение?
Ядра два, а приложение может создавать потоков сколько угодно, тестировал с 3 потоками...

Добавлено через 21 минуту
Сообщение от volvo
А между тем, я тебе показывал именно с такой проверкой: Мониторинг директории и копирование только новых файлов (на 22-ю строку обрати внимание)
Да, проверка пока не terminate у меня есть, но вот почему-то они все равно не останавливались, ну да ладно.
В общем добавление нового потока при добавлении новой директории для мониторинга я сделал, все вроде работает как надо. Количество запущенных потоков я подсчитываю, все вроде хорошо. Однако как решить обратную задачу? Как мне при удалении директории остановить именно тот поток, который за ней смотрел?

Добавлено через 20 минут
Удаление мониторинга и останов потока сделал так:
C++
1
2
int cThdel=DBGrid1->DataSource->DataSet->RecNo-1;
ArrayThread[cThdel]->Terminate();
Вроде работает...
Подскажите как используя Sleep() снизить нагрузку?

Добавлено через 26 минут
Попробовал так:
C++
1
2
3
4
5
while(!Terminated)
{
........
Sleep(100)
}
Наблюдаю....

Добавлено через 18 часов 43 минуты
Всем привет!
Итоги вчерашних изысканий.
C++
1
2
3
4
5
while(!Terminated)
{
........
Sleep(100)
}
позволило снизить нагрузку примерно в 5 раз.
решение по удалению
C++
1
2
int cThdel=DBGrid1->DataSource->DataSet->RecNo-1;
ArrayThread[cThdel]->Terminate();
выдавало ошибку если попытаться удалить только что созданный поток, т.е. работало корректно только если добавить поток, перезапустить приложение и только потом удалить этот поток. В этой связи обзавелось костылем в виде try - cath и функции по перезапуску приложения.
Вопрос: Приостановить выполнения дочернего потока

В классе ChildrenThread нужно реализовать методы для приостановки и продолжения выполнения потока. Приведенный мной пример, очень утрирован относительно реальной задачи. Метод run() выполняется очень долго и у пользователя может возникнуть необходимость приостановить его работу, независимо от этапа выполнения задачи...


Пробовал сделать так:

Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    class ChildrenThread extends Thread {
     
        private volatile boolean play = true;
     
        public ChildrenThread() {
        }
     
        @Override
        public void run() {
            int i = 0;
            while (!isInterrupted()) {
                System.out.println(i++);
            }
        }
     
        public synchronized void play() {
            play = true;
            notify();
        }
     
        public synchronized void pause() {
            play = false;
            while (!play) {
                try {
                    wait();
                } catch (InterruptedException ex) {
                }
            }
        }
Пример использования:

Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    public static void main(String[] args) throws InterruptedException {
        ChildrenThread th = new ChildrenThread();
     
        th.start();
            Thread.sleep(100);
     
        th.pause();
            Thread.sleep(5000); 
     
        th.play();
            Thread.sleep(50);
     
        th.pause();
            Thread.sleep(10000);
        
        th.play();
        th.interrupt();
    }
В этом примере, выполнение главного потока останавливается при первом вызове pause() дочернего потока, а сам дочерний поток продолжает выполнение.

Как сделать так, чтобы при вызове pause(), приостанавливал свою работу дочерний поток и продолжал ее после вызова метода play() ?
Ответ:
Уберите, потому что он снова приостанавливает поток:
Java(TM) 2 Platform Standard Edition 5.0
1
Thread.sleep(50);
Этот sleep, должен приостанавливать выполнение главного потока, а перед этим был запущен ( th.play(); ) дочерний поток, он должен выполнятся независимо от состояния главного...
Конечно же, мой код из первого сообщения работает только в теории.
На практике в java существует ограничение на приостановку работы других потоков (т. е. wait и sleep применимы только для потока из которого вызывается).
На свой вопрос я уже ответил
Как вариант, для решения этой задачи можно сделать так:

Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class ChildrenThread extends Thread {
 
    public volatile boolean play = true;
 
    @Override
    public void run() {
        int i = 0;
        while (!isInterrupted()) {
            checkPause();
            System.out.println(i++);
        }
    }
 
    public synchronized void play() {
        play = true;
        notify();
    }
 
    public void pause() {
        play = false;
    }
 
    private synchronized void checkPause() {
        while (!play) {
            try {
                wait();
            } catch (InterruptedException ex) {
            }
        }
    }
}
Вопрос: Приостановка потоков

Здравствуйте, помогите, пожалуйста, разобраться с заданием.
Создать 2 потока: поток 1 выполняет вычитание и поток 2 выполняет деление. Потоки самостоятельно после выполнения математических операций переходят в приостановленное состояние. Из главного потока через 1 секунду возобновить их выполнение, позволив корректно завершиться.
Написал, код, пока что без математических операций. У меня получилось так, что при приостановке останавливается только 1 поток, а второй продолжает работать, как решить проблему ?

Кликните здесь для просмотра всего текста


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
 
namespace LaboratoryWork_1
{
    class Program
    {
        static void Main()
        {
            //Управление первым потоком
            Thread One_thr = new Thread(OneThread);
            ManualResetEvent One_me = new ManualResetEvent(true);
 
            Thread Two_thr = new Thread(TwoThread);
            ManualResetEvent Two_me = new ManualResetEvent(true);
 
            One_thr.Start(One_me);
            Thread.Sleep(5000);
            One_me.Reset();
            Console.WriteLine("Pause");
            Thread.Sleep(2000);
            Console.WriteLine("Run");
            One_me.Set();
            Thread.Sleep(5000);
            One_me.Reset();
 
            Console.ReadKey();
        }
 
        static void OneThread(object state)
        {
            //Первый потока, который выводит "one"
            ManualResetEvent One_MRE = (ManualResetEvent)state;
            Thread Two_thr = new Thread(TwoThread);
            Two_thr.Start();
 
            for (int y = 100000; y > 0; y--)
            {
                One_MRE.WaitOne();
                Thread.Sleep(200);
                Console.WriteLine("one");
 
                ManualResetEvent One_me = new ManualResetEvent(true);
            }
        }
 
        static void TwoThread(object state)
        {
            //Воторой поток, который выводит "two"
            for (int y = 100000; y > 0; y = y--)
            {
                Thread.Sleep(250);
                Console.WriteLine("two");
            }
        }
    }
}
Ответ:
Сообщение от TopLayer
CLR итак держит по одному ManualResetEvent на поток. А Monitor.Wait его использует.
Спасибо, как то упустил этот момент с Monitor.Pulse / Wait
Вопрос: Форма в отдельном потоке мигает и исчезает, а должна висеть

Доброго времени.

Думал, с потоками за пару лет разобрался, и сюрпризов больше не будет, но вот непонятная вещь, и я не понимаю. что делаю не так.
Форма question1 должна появиться и висеть, а она мигает на долю секунды и исчезает.
Программа должна последовательно для каждого файла из списка открыть файл в excel, вывести форму question1, после нажатия кнопки на question1 - обработать файл. И по новой.

код:

vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    Public Sub Main(ByVal files As String())
 
        Excel = CreateObject("Excel.Application")
        For k = 0 To files.Length - 1
 
            WorkBook = Excel.Workbooks.Open(files(k)) 'открывается
            ExSheet = WorkBook.ActiveSheet
            Excel.Visible = True ' показывает
            trd1 = New Thread(AddressOf question_f)
            trd1.Start() ' стартует
 
            Do Until question1.Visible = True 'если поставить тут точку остановки, понятно что основной поток зацикливается тут
                Thread.Sleep(1000)
            Loop
 
        Next
    End Sub
 
    Sub question_f()
        question1.Visible = True
        question1.Show() 'показывает, но тут же исчезает
    End Sub 'может дело в том, что завершается этот раздел, и поток "обнуляется"?
Код формы question1:

vb.net
1
2
3
4
5
6
7
8
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ReadExcel.obr() 'обработка, до нее, естественно, не доходит
    End Sub
 
    Private Sub question1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Visible = True
        Me.TopMost = True
    End Sub
Ответ: В моем понимании так получается:

Когда вы используете Form.Show, тогда у вас поток, который вызвал форму не блокируется и продолжает свою работу, и как только он закончил выполнения своего кода, он автоматически останавливается и закрывает самого себя, и конечно же все то, что он на создавал, включая вашу показанную форму... Ведь вы когда выполняете Me.Close() тоже ведь все открытые формы вместе с основынфм потоком дружненько закрываются?

А в случае с Form.ShowDialog(), форма, вызванная как диалог, блокирует поток, который ее вызвал до момента закрытия этой формы, скажем так - ставит на паузу, и весь код, идущи после вызова данным способом - приостанавливается, до получения DialogResult от диалогового окна... После закрытия формы, поток продолжает свою работу и по достижении конца, выгружается...

Вот такая логика.

Добавлено через 3 минуты
для проверки данной теории, попробуйте после Form.Show() добавить простую паузу, например вот так:
vb.net
1
2
3
4
5
    Sub question_f()
        question1.Visible = True
        question1.Show() 
        Threading.Thread.Sleep(1000) 'пауза на секунду, после чего форма закроется сама
    End Sub
Вопрос: Поток ввода cin

Привет.
Я только начинаю учить C++, так что не смейтесь если проблема примитивная, но всё равно прошу помочь
Учусь по книге Страуступа. Выполнял упражнение (5.10), и у меня возникла проблема. После заноса в вектор значений с помощь цикла и потока cin жму Enter и ничего не происходит. Поток останавливается только тогда когда я ввожу какой то другой символ (букву или что то типа /). А после этого сразу выводят все сообщения cout и я написано "Нажмите для завершения программы". Никак не могу реализовать занос числа в переменную b с помощью cin. Что делать?

Вот сам код

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <Windows.h>
 
using std::endl;
using namespace std;
inline void keep_window_open() { char ch; cin>>ch; }
 
//считает сумму первых N, введёных чисел.
//не смог разобраться как прервать поток cin и начать новый.
int main() 
{
    SetConsoleCP(1251); // установка кодовой страницы win-cp 1251 в поток ввода
    SetConsoleOutputCP(1251); // установка кодовой страницы win-cp 1251 в поток вывода
    
    vector<int> chisla;
    int a;
    int i=0;
    int b=0;
    int sum=0;
    cout<<"Пожалуйста, введите несколько чисел: ";
    while (cin>>a) {
        chisla.push_back(a);
        ++i;
    }
    cout<<"Пожалуйста, введите количество чисел, которые хотите просуммировать (начиная с первого): ";
    cin>>b; //не могу начать поток ввода
    for (int m=0; m<b; ++m) {
        sum+=chisla[m];
    }
    cout<<"Сумма первых " <<b<<" чисел: "<<sum<<endl;
    return 0;
}
Ответ: Надо поток ввода очищать. Вот код:

C++
1
2
    cin.clear();
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');