Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2002.05.09;
Скачать: [xml.tar.bz2];

Вниз

Как считать значение переменной в другом потоке?   Найти похожие ветки 

 
Frogkiller   (2002-02-28 23:06) [0]

Уважаемые господа-товарищи профи! Подскажите плз, как из одного потока считать значение переменной, принадлежащей другому потоку. А то, знаете ли, лаба в 8.00, а прога-то не работает никак...


 
VuDZ   (2002-03-01 00:32) [1]

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

PS а чем это ты занимался на лекциях???


 
ZZ   (2002-03-01 00:52) [2]

2 VuDZ
А ты пиши на OP - ты же Мастер Delphi. Ждемс.


 
VuDZ   (2002-03-01 01:50) [3]

wow! не видел :>
ладно. предположим так (почти всё - чисое API + C)

// это первая ф-ия, оторая имеет некую переменную
void func1(void *param){
int n = 1; // это наша переменная
// когда начинается новый поток, ему передаётся
// определяемая пользователем (программёром) переменная -
// указатель на что угодно
// соответсвенно, мы можем её "натравить" на нужную пересенную:
param = &n; // т.е. взять адрес n и присвоить его param
....... // do anything
}

// this is another thread
void func2(void *param){
if (param != NULL)
*(int*)param = 10;
}

// body of main thread
.......
void * v = NULL;
_beginthread(func1, v);
Sleep(0);
_beginthread(func2, v);
}


а теперь по порядку:
1. заводиться переменная, которая может указывать на всё, что угодно. Это надо смотреть в help"e по паскалю, как это обозначается, на С - LPVOID
2. создаётся новый поток, которому передаётся эта переменная, и значение которой он устнавливает равным адресу своей переменной
3. создаётся другой поток. перед этим вызыватся ф-ия API Sleep(0), которая просто отдаёт управление другому потоку, в данном слчае - fuct1(). потом лишь создаётся второй поток, которому то же передаётся эта же переменная, и соответственно, так как они находяться в одном адресном прострнстве. могут менять значени n.

меры предосторожности: так как это всё реализовано на примитивниеёшем уровне, то рекомендуется не изменять значение n в первом потоке, иначе возможны проблемы, хотя для 4х байт это мало вероятно.

всё вышенаписанное является почти полнвым ответом на экзамене на первоначальный вопрос, только вот надо будет сначала объяснить IPC (inter process comunication) :>

удачи


 
Frogkiller   (2002-03-01 03:04) [4]

Спасибо большое. Только что-то Sleep не работает - хочет чтоб его объявили. В хелпе:
procedure Sleep(dwMilliseconds: DWORD); stdcall;
А компилятор на это говорит что DWORD он вобще первый раз в своей жизни видит и что ему на него... Вот такие дела.


 
VuDZ   (2002-03-01 04:16) [5]

DWORD - 32х битная целочисленная беззнаковая переменная, можно объявить как integer, это не важно.


 
Raptor   (2002-03-01 12:42) [6]

Чего то ты здесь очень много нагородил (хотя все правильно), а оно делается намного проще. :-))
Надо только описать переменную в области видимости всех нитей.
Для этого, например, создаем новый модуль и в интерфейсной его части описываем нужную нам переменну. Потом вносим этот модуль в Uses всех модулей где описаны нити. Тогда все нити смогут обращаться к этой пременной, правда придется позаботиться о синхронизации доступа.



 
VuDZ   (2002-03-01 15:42) [7]

я об этом подумал когда засыпал - примерно в 5 утра :>
но с другой стороны:
> как из одного потока считать значение переменной, принадлежащей
> другому потоку


так что это не совсем корректно, создавать глобальную переменную


 
Юрий Зотов   (2002-03-01 20:05) [8]

type
TMyThread = class(TThread);
private
FVar: integer;
...
public
property Var:integer read FVar write FVar;
end;

И все. Теперь переменная FVar имеет свое собственное значение в КАЖДОМ потоке и доступна откуда угодно через свойство Var.


 
VuDZ   (2002-03-01 20:57) [9]

offtop:
а теперь предположим такое: у нас есть 2-3 десятка различных потоков, которые обрабатывают некоторые данные и возвращают то же (in - anythin, out - int, float, string), и есть потоки, которые принимают обработанные данные и используют. и как тут быть, с учётом того, что каждый поток не знает своего "источника".
Это можно сделать со свойствами, но только через наследование от нескольких базовых типов с виртуальным DoWork() или как это там называется, т.е.

class IntThread
propetry Int......
end;

class FloatThread
property Float .....
end;

и уже от них наследовать свои потоки

I"m sorry for my flame :>

PS в винде, в отличие от VCL & MFC & etc. - поток - это функция, а не класс, но я думаю, это знают почти все


 
Raptor   (2002-03-02 01:29) [10]

2 VuDZ
так что это не совсем корректно, создавать глобальную переменную

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

2 Юрий Зотов
Это все, конечно, правильно. Только вот это не очень подходит если потоки не однотипны или реализация пишется только на API без использования VCL.

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


 
VuDZ   (2002-03-02 02:40) [11]


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

Тут небольшое логическое противоречие:
Ему нужен доступ к переменной в другом потоке и Так почему бы ему не сделать эту переменную глобальной

Т.е. эта переменная внутри, она локальна для потока. так что тут есть небольшая разница

А проблемы с указателями - это мелочи, на самом деле отличная вещь


 
Cobalt   (2002-03-02 09:40) [12]

2 Юрий Зотов © (01.03.02 20:05)
ИМХО, Должно быть так:
type
TMyThread = class(TThread);
private
FVar: integer; threadvar;
...

Тогда это действительно локальная переменная потока, сохраняемая в стеке этого потока
Ведь все потоки одного процесса разделяют одну область данных
2 VuDZ © (02.03.02 02:40)

Из Using Delphi
Reference-counted variables (such as long strings, dynamic arrays, or interfaces) are not thread-safe, even if they are declared with threadvar. Do not use dynamic thread variables, since there is in general no way to free the heap-allocated memory created by each thread of execution. Finally, do not create pointer- or procedural-type thread variables.


 
Raptor   (2002-03-04 18:58) [13]

2 VuDZ
Никакого противоречия здесь нет. Я говорю, что если ему нужен доступ к локальной переменной потока, то тогда не лучше ли ему запрограммировать поток так, что бы этого делать не пришлось. Тоесть сделать переменную глобальной, тогда с доступом проблем не будет.
А насчет указателей я с тобой согласен - вещь отличная, но я стараюсь, по возможности, обходится без них, особенно если иными методами сделать то же самое намного проще. Дело в том что они очень запутывают код. Если обратиться к коду с указателями через некоторое время (пол года - год) в нем довольно трудно разбираться. И переносимость такого кода намного хуже.


 
Юрий Зотов   (2002-03-04 21:09) [14]

> Raptor © (02.03.02 01:29)

1. > Только вот это не очень подходит если потоки не однотипны
Кто мешает плодить разнотипные потоки от общего предка?

2. > или реализация пишется только на API без использования VCL.
В студенческой лабораторной работе?

3. > автору вопроса не мешало бы уточнить...
Вот это точно.

4. Глобальная переменная может иметь только ОДНО значение, общее для всех потоков. В вопросе речь идет о другом.


> Cobalt © (02.03.02 09:40)

1. В примере каждый экземпляр класса TMyThread имеет свою переменную FVar и свою функцию потока. Сопоставление однозначное. Синхронизация (если нужна) делается любым обычным способом.

2. Тоже из Using Delphi:

"A thread-local variable is like a global variable, except that each thread of execution gets its own private copy of the variable, which cannot be accessed from other threads."

В вопросе поставлена прямо противоположная задача.


 
VuDZ   (2002-03-04 23:04) [15]

Господа, не сорьтесь :>


> 2. > или реализация пишется только на API без использования
> VCL.
> В студенческой лабораторной работе?

Почему-бы и нет? Для меня было бы проще сделать в делфи именно так (правда в консольном приложение, а то не помню, какую переменную надо определить для VCL, что бы она была многопоточно-учтойчивой (ну и словечко :> ) )


> "A thread-local variable is like a global variable, except
> that each thread of execution gets its own private copy
> of the variable, which cannot be accessed from other threads."

Это всё конечно хорошо для ООП, но не забывайте. что винда - это не ОО система, и тут форум о winAPI, вроде пока что был :>

Frogkiller, ау!
Или уже исключили?


 
Raptor   (2002-03-04 23:25) [16]

2 Юрий Зотов.
4. Глобальная переменная может иметь только ОДНО значение, общее для всех потоков. В вопросе речь идет о другом.

О чем другом? Автор вопроса спросил как получить доступ к локальной переменной потока, а я ответил, что лучше изменить сам подход и определить пременную глобально. При этом поток не надо переделывать вообще. Он себе пишет в переменную как и раньше, и при этом есть доступ к этой переменной. Это только временная мера. Ему же надо было срочно, лабка горела.

И вообще надо, что бы автор откликнулся. А то мы здесь ругаемся, а ему, наверное, все это давно уже не нужно. ;-))





 
VuDZ   (2002-03-05 03:49) [17]


> Frogkiller © (28.02.02 23:06)


> А то, знаете ли, лаба в 8.00, а прога-то не работает никак...



> И вообще надо, что бы автор откликнулся. А то мы здесь ругаемся,
> а ему, наверное, все это давно уже не нужно. ;-))


His dead Jim, his dead (c) Pulp fiction :>



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2002.05.09;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.005 c
1-26077
MVova
2002-04-25 16:49
2002.05.09
Альтернатива SourceSafe


1-26186
Чужой
2002-04-25 15:44
2002.05.09
Как поменять текст на кнопке при нажатии на эту же кнопку?


6-26216
cypher
2002-02-17 23:54
2002.05.09
Конкетный вопрос


1-26050
Невидимка
2002-04-25 18:43
2002.05.09
Как скрыть пункт в ComboBox?


3-26036
Лёша
2002-04-17 05:24
2002.05.09
Можно ли из UDF запустить хранимую процедуру.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский