2017-02-08 12 views
2

У меня есть программа, которая имеет 2 потока, 1 для GUI, другая для работы в фоновом режиме. Это сервер, которому нужен GUI (не могу объяснить, почему), и он сообщает о некоторых входящих буферах в графический интерфейс. Для этого рабочий поток работает все время, не может приостанавливаться или клиенты будут таймаутом.Отправка сообщений из потока в поток без ожидания

Таким образом, проблема заключается в следующем: я не могу понять, как отправлять/получать сообщения из потоков, не дожидаясь. Что-то вроде: проверьте, появилось ли сообщение (каждые 1000 мсек), если да, то это сообщение содержит строку, которая должна быть «нажата» в GUI, если нет, продолжайте. И это работает в графическом интерфейсе, поэтому он не должен ждать, или ОС «подумает», что программа не отвечает.
Отправлять и получать в D ждать сообщений, которые я не хочу.

Что я пробовал:
объявить переменную в пространство имен модуля, то основной поток, и рабочий, и доступ к нему. Что-то вроде:

import std.concurrency; 
import std.stdio; 

ubyte someVar; 

void main(){ 
    //main thread: 
    //spawn child thread 
    writeln("someVar in thread#0:",&someVar); 
    spawn(&childThread); 
} 

void childThread(){ 
    writeln("someVar in thread#1:",&someVar); 
} 

НО, я обнаружил, используя код выше, что каждый поток получает иметь свою собственную someVar.
Что-то еще, что я пробовал:
Я пытался посылать указатель на someVar (сверху, например) в качестве сообщения для рабочего потока, сразу после запуска нити, и получать сообщения в рабочем потоке, как только он начинает (поэтому никаких сообщений не хватает). Но я узнал, что передача данных в локальном потоке не допускается в D.

Подводя итог: как я могу передавать сообщения (строки) из потока в поток, не помещая принимающий поток ждать сообщений?

+0

В вашем примере вы можете отметить ' someVar' как ['__gshared'] (https://dlang.org/spec/attribute.html#gshared). – sigod

+0

@sigod '__gshared' предназначен только для привязки к глобальным переменным C. Вы можете пометить D-переменные, но система типов будет относиться к ней как к локальному потоку, и вы можете получить неправильное поведение. Как и раздражает, D-код, который хочет использовать переменные обмена, действительно должен использовать 'shared'. –

ответ

2

НО, я обнаружил, используя код выше, что каждый поток получает свой собственный someVar.

В D переменные являются нито-локальными, если они не отмечены как shared. Итак, если вы хотите использовать такую ​​переменную для обмена данными, вам нужно объявить ее как shared и иметь дело с блокировкой переменной соответствующим образом. Если вы действительно хотите сделать это, я предлагаю читать

http://ddili.org/ders/d.en/concurrency_shared.html

Однако std.concurrency был разработан с передачей сообщений в виду, и он имеет send и receive функции для именно то, что избавляет от необходимости для shared. receive блокирует в ожидании сообщения, но вместо этого вы можете использовать receiveTimeout, а в документации, если таймаут отрицательный, он не будет ждать вообще. Если вы хотите идти по этому пути (который является рекомендуемым способом борьбы с нитями, разговаривать друг с другом в D), то я предлагаю вам прочитать:

http://ddili.org/ders/d.en/concurrency.html