Тема: Потоки

Почав вчити потоки, але щось нічого не зрозуміло. У першому кроці викликаються два потоки одночасно (напевно), як мені зробити затримку у створеному потоці "pt"?  Ось цей метод (std::this_thread::sleep_for) виконується в main-і (на 5 мілісекунд).
А як мені його задіяти для "st"? Потрібно використовувати його в функції, чы яккк? Скоріш за все, я неправильно зрозумів щось підкажіть будь ласка.

#include <iostream>
#include <thread>
#include <string>

#include <chrono>
 
void print(int num,int pos) {

    if (pos == 1) {
        for (int i = 0; i < num; i++) {
            std::cout << "------------------ " << i << std::endl;
            std::this_thread::sleep_for(std::chrono::seconds(2));
        }
    }
    else {
        if (pos == 2) {
            for (int i = 0; i < num; i++) {
                std::cout << i - num + 1 << " ------------------" << std::endl;
                std::this_thread::sleep_for(std::chrono::seconds(1));
            }
        }
    }

}


int main(){

    setlocale(LC_ALL, "Ukr");
    int num = 5;
    std::thread pt(print, num,1);
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
    print(num, 2);
    
    pt.detach();
    
    


    return 0;

}

Re: Потоки

if (pos == 1) {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
        for (int i = 0; i < num; i++) {
            std::cout << "------------------ " << i << std::endl;
            std::this_thread::sleep_for(std::chrono::seconds(2));
        }
    }

Якщо вставити перед циклом в if, то працює, але як зробити main?

3 Востаннє редагувалося koala (12.01.2021 15:42:19)

Re: Потоки

Я не зовсім зрозумів, у чому саме проблема. Там є проблема з detach - має бути join, інакше програма завершується і вбиває потік, detach захищає від знищення об'єкту, але не всього процесу. Але всі затримки працюють, як належно.
Можете пояснити, що виводить у вас програма і на що ви очікували?

Re: Потоки

koala написав:

Я не зовсім зрозумів, у чому саме проблема. Там є проблема з detach - має бути join, інакше програма завершується і вбиває потік, detach захищає від знищення об'єкту, але не всього процесу. Але всі затримки працюють, як належно.
Можете пояснити, що виводить у вас програма і на що ви очікували?

А join або detach потрібно використовувати перед завершенням головного потоку?  Бо я пробував detach вставити в різні фрагменти коду, працює одинаково.join щось по-різному.

5

Re: Потоки

І join, і detach працюють однаково де завгодно, і їх треба використовувати там, де вам це потрібно. Не намагайтеся відгадати, що вони роблять - прочитайте, якщо незрозуміло - поекспериментуйте. І якщо надалі ігноруватимете мої питання - я вам нічим допомогти не зможу.

Re: Потоки

koala написав:

І join, і detach працюють однаково де завгодно, і їх треба використовувати там, де вам це потрібно. Не намагайтеся відгадати, що вони роблять - прочитайте, якщо незрозуміло - поекспериментуйте. І якщо надалі ігноруватимете мої питання - я вам нічим допомогти не зможу.

Перепрошую, не замітив. Могли б Ви глянути код? Потрібно вивести одночасно 2 рядочки тексту( черги та стеку) але я зміг вивести їх тільки вертикально... Не знаю як зробити горизонтально.

Ось код

#pragma once
#include <string>

class node {
   
    public:

        std::string name;
        std::string index;
        class node* nextnode;

        node* returnnewnode(std::string);
        std::string returnindex(std::string);
};

class line : public node {

    private:
        std::string** mass;
        int numqueue;
        int numstack;
        class node* queue;
        class node* stack;
        

    public:

        line();
        int returnnum(std::string);
        void name(std::string);
        void fullline(std::string);
        void print(std::string);
        void printmass(std::string);

};


#include "line.h"
#include <iostream>
#include <thread>
#include <chrono>


node* node::returnnewnode(std::string index) {

    class node* newnode = new node;
    newnode->index = index;
    newnode->nextnode = nullptr;
    return newnode;

}


std::string node::returnindex(std::string name) {
    
    std::cout << "Введіть індекс нового елементу ";
    if (name == "stack") {
        std::cout << "стеку: ";
        std::string index;
        std::cin >> index;
        return index;
    }
    else {
        if (name == "queue") {
            std::cout << "черги: ";
            std::string index;
            std::cin >> index;
            return index;
        }
    }

}


void line::name(std::string name) {

    if (name == "queue") {
        std::cout << "Введіть к-сть елементів черги: ";
        std::cin >> numqueue;
    }
    else {

        if (name == "stack") {
            std::cout << "Введіть к-сть елементів стеку: ";
            std::cin >> numstack;
        }
    }
    return;

}


void line::fullline(std::string name) {
    if (name == "queue") {
        if (queue == nullptr) {
            std::string index = node::returnindex(name);
            class node* newnode = node::returnnewnode(index);
            queue = newnode;
        }
        else {
            if (queue != nullptr) {
                class node* findlast = queue;
                while (findlast->nextnode != nullptr) {
                    findlast = findlast->nextnode;
                }
                std::string  index = node::returnindex(name);
                class node* newnode = node::returnnewnode(index);
                findlast->nextnode = newnode;
            }
        }
    }else {
        if (name == "stack") {
            if (stack == nullptr) {
                std::string  index = node::returnindex(name);
                class node* newnode = node::returnnewnode(index);
                stack = newnode;
            }
            else {
                if (stack != nullptr) {
                    std::string  index = node::returnindex(name);
                    class node* newnode = node::returnnewnode(index);
                    newnode->nextnode = stack;
                    stack = newnode;
                }
            }
        }
    }
    return;

}

void line::print(std::string name) {
    if (name == "queue") {
        class node* printline = queue;
        int i = 0;
        while (printline != nullptr) {
            if (printline->nextnode == nullptr) {
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                std::cout << printline->index;
                mass[i][1] = printline->index;
                i = i + 1;
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                std::cout << "-";
                mass[i][1] = "|";
                i = i + 1;
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                std::cout << ">";
                mass[i][1] = "+";
                i = i + 1;
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                std::cout << "nullptr";
                mass[i][1] = "n";
                i = i + 1;
                mass[i][1] = "u";
                i = i + 1;
                mass[i][1] = "l";
                i = i + 1;
                mass[i][1] = "l";
                i = i + 1;
                mass[i][1] = "p";
                i = i + 1;
                mass[i][1] = "t";
                i = i + 1;
                mass[i][1] = "r";
                i = i + 1;
                printline = printline->nextnode;
            }
            else {
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                std::cout << printline->index;
                mass[i][1] = printline->index;
                i = i + 1;
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                std::cout << "-";
                mass[i][1] = "|";
                i = i + 1;
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                std::cout << ">";
                mass[i][1] = "+";
                i = i + 1;
                printline = printline->nextnode;
            }
            
        }
    }
    else {
        if (name == "stack") {
            int i = 0;
            class node* printline = stack;
            while (printline != nullptr) {
                if (printline->nextnode == nullptr) {
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                    std::cout << printline->index;
                    mass[i][0] = printline->index;
                    i = i + 1;
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                    std::cout << "-";
                    mass[i][0] = "|";
                    i = i + 1;
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                    std::cout << ">";
                    mass[i][0] = "+";
                    i = i + 1;
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                    std::cout << "nullptr";
                    mass[i][0] = "n";
                    i = i + 1;
                    mass[i][0] = "u";
                    i = i + 1;
                    mass[i][0] = "l";
                    i = i + 1;
                    mass[i][0] = "l";
                    i = i + 1;
                    mass[i][0] = "p";
                    i = i + 1;
                    mass[i][0] = "t";
                    i = i + 1;
                    mass[i][0] = "r";
                    i = i + 1;
                    printline = printline->nextnode;
                }
                else {
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                    std::cout << printline->index;
                    mass[i][0] = printline->index;
                    i = i + 1;
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                    std::cout << "-";
                    mass[i][0] = "|";
                    i = i + 1;
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                    std::cout << ">";
                    mass[i][0] = "+";
                    i = i + 1;
                    printline = printline->nextnode;
                }

            }
        }
    }
    return;

}


line::line() {

    mass = new std::string * [20];
    for (int i = 0; i < 20; i++) {
        mass[i] = new std::string[2];
        
    }
    
    for (int i = 0; i < 20; i++) {
        for (int j = 0; j < 2; j++) {
            mass[i][j] = "99999";
        }
    }

}


int line::returnnum(std::string name) {
    
    if (name == "stack") {
        return numstack;
    }
    else {
        if (name == "queue") {
            return numqueue;
        }
    }
}


void line::printmass(std::string name) {

    if (name == "stack") {
        for (int j = 0; j < 20; j++) {
            if (mass[j][0] != "99999") {
                std::this_thread::sleep_for(std::chrono::seconds(1));
                std::cout << mass[j][0] << "   #" << std::endl;
            }
        }
    }
    else {
        if (name == "queue") {
            for (int j = 0; j < 20; j++) {
                if (mass[j][1] != "99999") {
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    std::cout << "#   "<< mass[j][1] << std::endl;
                }
            }
        }
    }
    return;

}


#include <thread>
#include <chrono>
#include <iostream>
#include"line.h"


int main(void) {

    setlocale(LC_ALL,"Ukr");

    class line qs;

    qs.name("queue");
    int numq = qs.returnnum("queue");
    for (int i = 0; i < numq; i++) {
        
        qs.fullline("queue");
    }
    qs.print("queue");
    std::cout << std::endl;

    qs.name("stack");
    int nums = qs.returnnum("stack");
    for (int i = 0; i < nums; i++) {

        qs.fullline("stack");
    }
    qs.print("stack");
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << std::endl;
    


    auto ret =[&qs](std::string name) {
        qs.printmass(name);
    };

    std::thread second(ret,"stack");

    qs.printmass("queue");
    
    second.join();

    return 0;
}

7

Re: Потоки

Львівский сирник в мульти написав:

Могли б Ви глянути код?

Нащо?

Львівский сирник в мульти написав:

Потрібно вивести одночасно 2 рядочки тексту( черги та стеку) але я зміг вивести їх тільки вертикально... Не знаю як зробити горизонтально.

А проблема в чому?

Re: Потоки

Коли виводити на консоль горизонтально стек і чергу, я не зможу переключатися між рядками, тому все буде одночасно виводитись у 1-ому,2-ому,3-ому і ТД. Ось придумав тільки що можна вивести вертикально (і то працює криво, довелось незаповнені клітинки заповнювати '#').

9 Востаннє редагувалося koala (13.01.2021 23:01:36)

Re: Потоки

Стандартна консоль не призначена для красивих ефектів. Можете використовувати якісь специфічні для ОС бібліотеки (як windows.h) чи кросплатформові (як ncruses); можете взагалі використовувати щось графічне. Але я б вам радив зосередитися не на красі ефектів, а на коректності роботи потоків.

10

Re: Потоки

Ви п.1.1 Правил бачили? При реєстрації галочку ставили?

11

Re: Потоки

Давайте українською! Не розумію вашої мови.

while(1) {
/* . . . */
}

Re: Потоки

lucas-kane написав:

Давайте українською! Не розумію вашої мови.

while(1) {
/* . . . */
}

Я так пробував, але вибиває помилку. І програма зупиняється .

13 Востаннє редагувалося Львівский сирник в мульти (16.01.2021 20:14:57)

Re: Потоки

Вимога було наступне:

Правильно розбити задачу на паралельність.
Синхронізувати потоки, зберегти цілісність даних. Адже обмежити доступ до загального ресурсу справа не складна, а змусити їх працювати злагоджено вже набагато складніше.
Робота генератора кораблів не повинна залежати від роботи причалів та навпаки.
Загальний ресурс повинен бути Thread Safe (Якщо такий є в реалізації)
Потоки не повинні бути активними якщо немає завдань.
Потоки не повинні тримати mutex якщо немає завдань

14

Re: Потоки

Тульський пряник іде в бан до понеділка.

15

Re: Потоки

Львівский сирник в мульти написав:
lucas-kane написав:

українською! не розумію вашої мови.

while(1) {
/* . . . */
}

Я так пробував, але вибиває помилку. І програма зупиняється .

Взагалі, то був жарт. Але якщо Ви вже так пробували... ))) (не маю що сказати)

16

Re: Потоки

Лудоман іде в перманентний бан за п.2.1 Правил.
Бан Сирнику тепер ще й по IP, до 20 числа.

Подякували: leofun011

17

Re: Потоки

koala написав:

Ви п.1.1 Правил бачили?

а ви бачили? там нічого не написано про бан за іншу мову. Невже так складно написати нормальні правила, які не допускають свавілля модераторів.

Re: Потоки

Thread Safe що це? Не можу знайти

19

Re: Потоки

https://uk.wikipedia.org/wiki/Багатониткова_безпека
В англійській версії є деталі, як її досягати.

20 Востаннє редагувалося Львівский сирник в мульти (26.01.2021 13:30:09)

Re: Потоки

const boost::system::error_code& що означає ось цей рядок? Бо на сайті він написаний в функції, але не використовується, мабудь.