Я думаю, это может быть довольно простой вопрос.
Я нашел много примеров использования потоков и общих переменных, но ни в одном примере общая переменная не была создана внутри потока. Я хочу убедиться, что я не делаю что-то, что, кажется, работает и когда-нибудь сломается в будущем.
Причина, по которой мне это нужно, в том, что у меня есть общий хеш, который сопоставляет ключи с ссылками на массивы. Эти ссылки создаются / заполняются одним потоком, а считываются / изменяются другим (предполагается правильная синхронизация). Чтобы сохранить эти ссылки на массивы, я должен сделать их общими. В противном случае я получаю ошибку Invalid value for shared scalar
.
Ниже приведен пример:
my %hash :shared;
my $t1 = threads->create(
sub { my @ar :shared = (1,2,3); $hash{foo} = \@ar });
$t1->join;
my $t2 = threads->create(
sub { print Dumper(\%hash) });
$t2->join;
Это работает, как и ожидалось: второй поток видит изменения, сделанные первым. Но так ли это при любых обстоятельствах?
Некоторые уточнения (относительно ответа Яна):
У меня есть одна нить, читающая из канала и ожидающая ввода. Если они есть, поток A запишет эти входные данные в общий хеш (он отображает скаляры в хэши ... это те хэши, которые также должны быть объявлены общими) и продолжает прослушивать канал. Другой поток B получает уведомление (через cond_wait
/ cond_signal
) о том, что нужно что-то делать, работает над содержимым в общем хэше и удаляет соответствующие записи после завершения. Тем временем А может добавлять новые вещи в хеш.
Так что по вопросу Яна
[...] Следовательно, большинство людей создают все свои общие переменные перед запуском каких-либо подпотоков.
Поэтому, даже если общие переменные могут быть созданы в потоке, насколько это будет полезно?
Общий хеш - это динамически растущая и сокращающаяся структура данных, которая представляет запланированную работу, над которой еще не работали. Поэтому нет смысла создавать полную структуру данных в начале программы.
Кроме того, программа должна состоять (как минимум) из двух потоков, потому что, конечно, чтение из конвейерных блоков. Более того, я не вижу способа сделать это без совместного использования переменных.