Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.64/88: Рейтинг темы: голосов - 88, средняя оценка - 4.64
0 / 0 / 0
Регистрация: 03.12.2017
Сообщений: 122

Как передать данные из одного потока в другой?

15.02.2018, 20:30. Показов 19476. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть отдельный поток для чтения данных и основной поток для обработки данных. Из этого потока данные нужно передать в основной поток.

Подскажите пожалуйста как это можно сделать


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
void read() {
    std::ifstream stream("C:\\Users\\..  ..txt");
    //  тело ф-ции
 
        while (!stream.eof()) {
            //тело цикла
            }
 
        }
        
void obrabotka() {
    //тело функции
 
}
 
int main() {
 
    thread func_read(readFile);
thread func_obr(obrabotka);
 
    func_read.join();
 
    cout << endl;
    system("pause");
 
    
    return 0;
 
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.02.2018, 20:30
Ответы с готовыми решениями:

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

Как передать переменную из одного файла в другой
Здравствуйте. Создал класс MainWindow в mainwindow.h : #ifndef MAINWINDOW_H #define MAINWINDOW_H #include &lt;QMainWindow&gt; ...

Как передать содержимое контейнера из одного модуля в другой?
Есть 2 модуля. Каждый модуль содержит файлы: *.h, *.cpp, *.pro. В файле *.h первого модуля описан QStringList список, в *.cpp этого же...

20
2 / 2 / 0
Регистрация: 17.06.2017
Сообщений: 10
15.02.2018, 21:26
volatile
Ну или std::atomic
1
73 / 69 / 38
Регистрация: 09.10.2012
Сообщений: 238
15.02.2018, 21:42
Лучший ответ Сообщение было отмечено NellkaKaramelka как решение

Решение

Создаете общедоступный буфер, например std::queue. В потоке чтения под мьютексом в этот буфер помещаете данные для обработки и сигналите std::conditional_variable. В потоке обработки ждете сигнала от этой std::conditional_variable и под мьютексом данные извлекаете.

Добавлено через 6 минут
Как то так. Код не проверял.

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
std::mutex mtx;
std::condition_variable cv;
std::queue<std::string> buf;
 
void read()
{
  // ...
  std::unique_lock<std::mutex> lck(mtx);
  buf.push("hello");
  cv.notify_one();
  //...
}
 
void process()
{
  while (true)
  {
    std::string data;
    {
      std::unique_lock<std::mutex> lck(mtx);
      while (buf.empty())
      {
        cv.wait(lck);
      }
 
      data = buf.top();
      buf.pop();
    }
 
    // process data
  }
}
2
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
15.02.2018, 21:52
Цитата Сообщение от Sergivus Посмотреть сообщение
volatile
И как он поможет?
1
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,910
16.02.2018, 10:50
Croessmah, заставит потоки действительно записывать значение в переменную, а не оставлять в регистрах. От фрагментации данных это, конечно, не спасет.

Добавлено через 3 минуты
Цитата Сообщение от NellkaKaramelka Посмотреть сообщение
Подскажите пожалуйста как это можно сделать
Кстати, тут никто не упомянул про каналы (pipes). Их можно сделать неблокирующими (в WinAPi - через костыли, как обычно). Если интересно, вот моя реализация (на Си а не С++, так что вопросы "почему не std::thread" не интересны).
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
16.02.2018, 10:57
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
От фрагментации данных это, конечно, не спасет.
Другими словами, ничем не поможет.
1
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,910
16.02.2018, 13:28
Для данных, обрабатывающихся атомарно, поможет. Хотя все равно лучше использовать нормальные атомарные типы
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
16.02.2018, 18:46
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Для данных, обрабатывающихся атомарно, поможет.
Несинхронизированный доступ к volatile-переменной из нескольких потоков это такое же UB, как и доступ к не-volatile переменным.
0
 Аватар для Nishen
1358 / 856 / 366
Регистрация: 26.02.2015
Сообщений: 3,814
16.02.2018, 19:15
COKPOWEHEU, как твой ник читать?!
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
16.02.2018, 19:31
Цитата Сообщение от Croessmah Посмотреть сообщение
И как он поможет?
Поможет только тем, что компилятор этот кусок кода (где проверяется переменная, которая в коде данного потока никак не модифицировалась) не выкинет при оптимизации. Больше отличий от обычной переменной нет.
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
16.02.2018, 19:37
Цитата Сообщение от Nishen Посмотреть сообщение
COKPOWEHEU, как твой ник читать?!
Молча!
0
0 / 0 / 0
Регистрация: 03.12.2017
Сообщений: 122
16.02.2018, 23:06  [ТС]
я про многопоточность читаю Энтони Уильямс "
Параллельное программирование на C++ в действии". По вашей подсказке нашла похожий материал на стр.113

Добавлено через 2 часа 52 минуты
а что если нужно создать еще один поток, в который нужно передать значение из строки data, чтобы записать значение в очередь? по какому принципу это можно реализовать? я это задание ни сама придумала
0
73 / 69 / 38
Регистрация: 09.10.2012
Сообщений: 238
16.02.2018, 23:14
Цитата Сообщение от NellkaKaramelka Посмотреть сообщение
а что если нужно создать еще один поток, в который нужно передать значение из строки data, чтобы записать значение в очередь?
Что-то я не очень понял.
0
0 / 0 / 0
Регистрация: 03.12.2017
Сообщений: 122
17.02.2018, 07:12  [ТС]
задание такое. один процесс считывает строку из файла и передает второму процессу переделать эту строку. второй процесс переделанную строку передает третьему процессу на запись
0
2734 / 888 / 331
Регистрация: 10.02.2018
Сообщений: 2,100
17.02.2018, 08:39
Вы уж определитесь, потоки у вас или процессы.
Вообще, передача данных между потоками одного процесса, это даже не совсем передача данных. Память у потоков общая и каждый поток в любой момент времени имеет к ней полный доступ. Вопрос не столько в передаче, сколько в выборе способа синхронизации действий. Синхронизацию можно построить кучей способов. Конкретный механизм взаимодействия потоков может зависеть от множества факторов, от объёмов и типа информации, нужен ли конвейер или просто последовательная обработка, для конвейера необходимо определиться с буферизацией и т.д. и т.п.
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "stdafx.h"
#include <stdlib.h>
#include <locale.h>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
 
#define TEXT_MAX_SIZE       1024
#define READ_THREAD_ID      1
#define TRANSFORM_THREAD_ID 2
#define WRITE_THREAD_ID     3
#define INVALID_THREAD_ID  -1
 
int g_iActiveThread = 0;
char g_chText[TEXT_MAX_SIZE];
std::mutex g_mutex;
std::condition_variable g_variable;
 
void ThreadRead();
void ThreadTransform();
void ThreadWrite();
 
bool GrantAccess(int iThreadID);
void DelegateAccess(int iThreadID);
 
int main()
{
    std::thread t1 = std::thread(ThreadWrite);
    std::thread t2 = std::thread(ThreadTransform);
    std::thread t3 = std::thread(ThreadRead);
 
    DelegateAccess(READ_THREAD_ID);
 
    t1.join();
    t2.join();
    t3.join();
 
    getchar();
 
    return 0;
}
 
void ThreadRead()
{
    char* pLines[] =
    {
        "Мороз и солнце; день чудесный!",
        "Еще ты дремлешь, друг прелестный -",
        "Пора, красавица, проснись:",
        "Открой сомкнуты негой взоры",
        "Навстречу северной Авроры,",
        "Звездою севера явись!"
    };
 
    size_t uLine = 0;
 
    while (GrantAccess(READ_THREAD_ID))
    {
        size_t uLineCount = sizeof(pLines)/sizeof(pLines[0]);
 
        if (uLine < uLineCount)
        {
            strcpy(g_chText, pLines[uLine++]);
 
            DelegateAccess(TRANSFORM_THREAD_ID);
        }
        else
        {
            DelegateAccess(INVALID_THREAD_ID);
        }
    }
}
 
void ThreadTransform()
{
    while (GrantAccess(TRANSFORM_THREAD_ID))
    {
        size_t uLineSize = strlen(g_chText);
        for (size_t i = 0; i < uLineSize / 2; i++)
        {
            char temp = g_chText[uLineSize - i - 1];
            g_chText[uLineSize - i - 1] = g_chText[i];
            g_chText[i] = temp;
        }
 
        DelegateAccess(WRITE_THREAD_ID);
    }
}
 
void ThreadWrite()
{
    setlocale(LC_ALL, "RU");
 
    while (GrantAccess(WRITE_THREAD_ID))
    {
        printf("%s\r\n", g_chText);
 
        DelegateAccess(READ_THREAD_ID);
    }
}
 
bool GrantAccess(int iThreadID)
{
    std::unique_lock<std::mutex> _lck(g_mutex);
 
    while (g_iActiveThread != INVALID_THREAD_ID)
    {
        if (g_iActiveThread == iThreadID)
            return true;
 
        g_variable.wait(_lck);
    }
 
    return false;
}
 
void DelegateAccess(int iThreadID)
{
    std::unique_lock<std::mutex> _lck(g_mutex);
    
    g_iActiveThread = iThreadID;
    g_variable.notify_all();
}
 
// вариант синхронизации без использования специальных объеков
//bool GrantAccess(int iThreadID)
//{
//    while (g_iActiveThread != INVALID_THREAD_ID)
//    {
//        if (g_iActiveThread == iThreadID)
//            return true;
//
//        std::this_thread::sleep_for(std::chrono::milliseconds(1));
//    }
//
//    return false;
//}
//
//void DelegateAccess(int iThreadID)
//{
//    g_iActiveThread = iThreadID;
//}
2
0 / 0 / 0
Регистрация: 03.12.2017
Сообщений: 122
17.02.2018, 08:58  [ТС]
ой, извините. задание по потокам. новичок в этом деле
0
0 / 0 / 0
Регистрация: 03.12.2017
Сообщений: 122
20.02.2018, 17:40  [ТС]
зацикливается под while(true)
0
73 / 69 / 38
Регистрация: 09.10.2012
Сообщений: 238
20.02.2018, 21:09
NellkaKaramelka, неудивительно, ведь это бесконечный цикл . Вам нужно позаботиться о выходе из такого цикла по какому-то условию. Например, по вводу "exit".
0
0 / 0 / 0
Регистрация: 03.12.2017
Сообщений: 122
21.02.2018, 06:57  [ТС]
всё исправила уже всем спасибо за внимание
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,910
21.02.2018, 11:25
А как же похвастаться тем, как именно исправлено
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.02.2018, 11:25
Помогаю со студенческими работами здесь

Как передать данные другой програме?
Написал програму по переводе целых чисел с одной системы счисления в другую, но проблема в том что это консоль, а хотелось-бы полноценное...

Как передавать динамически данные из одного класса в другой?
Есть такая проблема. Пишу игру с другом. Код выкладывать не буду потому что он большой :cry: Никто даже не захочет его смотреть, просто...

Передать значения из одного укахателя в другой
И снова глупый вопрос по указателям! Их количество стремится к бесконечности. Имеется функция, которая возвращает двумерный массив...

Передать значения из одного цикла в другой
Есть к примеру такой кодint z (разные значения) ; for (int i = 0; i &lt; 10; i++ ,z++) { z = z + 5; } int a ; for (int i =...

Передать константу с одного файла в другой по ссылке
Товарищи, нужна помощь! Хочу передать константу с одного файла в другой. Есть константа в одном файле extern const int size=10; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru