Jump to content

nedo

Active Members
  • Posts

    2065
  • Joined

  • Last visited

  • Days Won

    11

Everything posted by nedo

  1. Ceea ce spui tu se numeste "shin splints" https://www.mayoclinic.org/diseases-conditions/shin-splints/symptoms-causes/syc-20354105 Deoarece nu alergi in mod normal, tibia nu e obisnuita cu socul alergarii. Pantofi special de aleregare, alergare pe durate mai mici la inceput, incalzire inainte de alergare, ai grija la postura/felul cum alergi/calci cand alergi. Cu timpul dispare.
  2. Bump, modificat pret inca o data.
  3. Bump, modificat pret, lasati raspuns in thread sau pm.
  4. Salut, vand 2 stick-uri de ram a cate 4 gb fiecare 1333 mhz cl9. 1 este Corsair, al 2-lea nu stiu exact ce marca(Postez anuntul pentru o ruda). pret pentru amandoua 230 (de la 270) lei sau 115 (de la 135) lei fiecare. Placutele sunt aproape noi. Pm daca sunteti interesati.
  5. Sau, nu te chinui citind asa si faci asa: std::string linie; ifstream f("text.txt"); while(getline(f, linie)) // citesti cate o linie(adica tot textul pana la intalnirea new line)cat timp nu ajungi la finalul fisierului { cout << linie << endl; // afisezi linia citita }
  6. nedo

    c++/c# algo

    Ai explicatii in cod. struct MemStr // structura ce stocheaza datele citite de la site { string mem; size_t marime; }; static size_t WriteMemStr(void* contents, size_t size, size_t nmemb, void* userp) // functia ce face citirea de la site { size_t realsize = size * nmemb; struct MemStr* mem = (struct MemStr*)userp; mem->mem.append((char*)contents, realsize); mem->marime += realsize; //cout << "contents: " << contents << endl << "mem->mem: " << mem->mem << endl; //cout << "marime mem.mem: " << mem->mem.size() << endl; if(mem->mem.size() == mem->marime) { return realsize; } else { return 0; } } int main() { std::ifstream fLinkuri("linkuri.txt"); // fisierul din care citesti link-urile(modifici numele fisierului) std::ifstream fProxy("proxyuri.txt"); // fisier in care ai proxy-urile if(!fLinkuri.is_open() || !fProxy.is_open()) // te asiguri ca ai deschis fisierele { cout << "Eroare la deschidere fisiere."; return 0; } CURL* curl = curl_easy_init(); // initializare curl if(!curl) { cout << "Eroare initializare curl: "; return 0; } std::string link; // citesti link in el std::string proxy; // citesti proxy in el int contor = 0; // pentru a schimba proxi-ul MemStr mem; // in mare parte nefolosita, totusi dupa fiecare executie a curl, in mem.memorie ai pagina din link-ul accesat mem.marime = 0; while(std::getline(fLinkuri, link)) { if(contor == 0) { std::getline(fProxy, proxy); } curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemStr); // functia executata pentru citirea datelor primite de la site curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&mem); // variabila in care se salveaza datele curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); curl_easy_setopt(curl, CURLOPT_URL, link.c_str()); // setam url-ul curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); // setam link-ul proxy-ului curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); // http://curl.haxx.se/libcurl/c/CURLOPT_PROXYTYPE.html alegi din descriere tipul de proxy pe care il poti folosi CURLcode retCode = curl_easy_perform(curl); // executam if(retCode != CURLE_OK) // verificam daca s-a executat cu succes { cout << "Eroare la executare curl: " << curl_easy_strerror(retCode); // afisam eroare daca e cazul } contor++; // incrementam contorul if(contor == 10) // il resetam daca au trecut 10 iterari { contor = 0; } mem.mem.clear(); // golim memoria variabilei in care stocam pagina mem.marime = 0; // setam marimea memoriei la 0(daca uiti sa faci asta, o sa primesti erori } return 0; }
  7. Un "ai" il poti scrie in oricare din limbajele pe care le-ai specificat. In oricare din cazuri este ceva extrem de dificil, pentru ca implica aplicarea unui numar foarte mare de algoritmi matematici. Din punctul meu de vedere, tot c++ pare a fi mai ok pentru asa ceva, intrucat hashkell erlang si prolog, daca nu ma insel sunt limbaje procedurale si sunt ceva mai greu de folosit(cel putin pana te obisnuiesti cu el). Ideal ar fi insa, sa lucrezi cu limbajul cu care esti cel mai familiarizat.
  8. Acelea sunt fisiere obiect. Codul sursa este compilat intai in cod obiect si abea apoi este "legat" intr-un executabil alaturi de alte bucatele de cod obiect. aici ai o explicatie legata de procesul de compilare al c++
  9. Ex-gamer si supravietuitor al unui alcoolic....(deci stiu foarte bine cat rau pot face ambele atat la nivel fizic, cat si la nivel psihic)
  10. pe aceeasi logica si bautul de alcool la greu e pierdere de vreme(doar ca ceva mai nociv fizic, pe cand jocurile poate sunt mai nocive psihic, efectul e acelasi cand sunt consumate in excess, dependenta, problema e ca la dependenta de alcool renunti mult mai greu), pana una alta la cat mai multi subscriberi si followeri.
  11. La multi ani si sa fi sanatos, ca de restul te ocupi tu @M2G
  12. Dar oare v-ati gandit ca de fapt probema nu e chatul/dislike-uri/rep power ci faptul ca va plangeti sau abuzati de ele ca niste copii de 10 ani? @AndreiMihai din toate dislike-urile alea doar 3-4 sunt luate pe nedrept, restul sunt luate numai la posturi complet inutile. Restul userilor, invatati sa: -Primiti feedback negativ -Nu mai abuzati de astfel de metode de feedback negativ -Sa nu va mai comportati ca niste copiii rasfatati carora li se ia jucaria(cand luati ban) -Sa nu mai considerati ca sunteti niste vedete(prin prisma activitatii pe care o aveti pe forum, buna sau rea, prin ceea ce postati, sau prin trecutul lor). Nu conteaza ce ai facut, te supui acelorasi reguli ca toata lumea. Prea multe exceptii de la regula fac regulile inutile si creaza haos.
  13. Hai sa intru si eu in cursa, ca tot sunt curios cum e.
  14. Gluma adevarata era ca voi chiar ati crezut ca asta e o gluma
  15. aerosol, nu am nevoie nici de avocat, nici de purtator de cuvant. Iti sugerez sa termini cu astfel de "interventii" sau o sa il urmezi si tu. Iti sugerez sa incerci si sa ai grija doar de posturile/discutiile tale. Totul s-a discutat aici la vedere, nu e cazul sa iei tu "apararea unui moderator".
  16. Deja complici lucrurile inutil. Nu mai tin minte cand "te-ai luat de gramatica mea", dar imi aduc aminte ca ti-am raspuns simplu, stiu ca am o gramatica proasta pentru ca niciodata nu am invatat la romana mai mult decat sa trec. Nu mi-a placut. Cat despre "calcularea banului", nu e cazul, o face forumul pentru mine automat. Iar daca iti purtam pica in vreun fel, aveai ban acum, pentru ca puteam la fel de bine sa iti dau direct rosu si acum erai banat. Am ales sa fiu indulgent si sa dau galben, care nu atrage banare la cumul de avertismente. Asa ca pana una alta, stai in banca ta si vezi-ti de treaba. Daca vreun admin/moderator avea ceva cu tine, iti garantez ca acum aveai ban de cel putin cateva ori.
  17. Pentru ca nu am ce raspunde, si din moment ce nici un alt admin nu a raspuns, inseamna ca si ei sunt de aceeasi parere. Mai mult ar trebui sa spuna mersi, ala era al 5-lea avertisment si ar fi trebuit sa ia ban. @Die1 alias reckon pentru voi oricine va arde de fiecare data cand va cacati pe regulile forumului, face abuz.
  18. @novice13 te rog sa postezi dovezi ca acel cont iti apartine, ai 24 de ore.
  19. March 2015 Security Incident and the Launch of Two Factor Authentication Posted March 27th, 2015 We were recently able to confirm that there was unauthorized access to a Slack database storing user profile information. We have since blocked this unauthorized access and made additional changes to our technical infrastructure to prevent future incidents. We have also released two factor authentication and we strongly encourage all users to enable this security feature. We are very aware that our service is essential to many teams. Earning your trust through the operation of a secure service will always be our highest priority. We deeply regret this incident and apologize to you, and to everyone who relies on Slack, for the inconvenience. Here is some specific information we can share about this incident: Slack maintains a central user database which includes user names, email addresses, and one-way encrypted (“hashed”) passwords. In addition, this database contains information that users may have optionally added to their profiles such as phone number and Skype ID. Information contained in this user database was accessible to the hackers during this incident. We have no indication that the hackers were able to decrypt stored passwords, as Slack uses a one-way encryption technique called hashing. Slack’s hashing function is bcrypt with a randomly generated salt per-password which makes it computationally infeasible that your password could be recreated from the hashed form. Our investigation, which remains ongoing, has revealed that this unauthorized access took place during a period of approximately 4 days in February. As soon as the evidence was uncovered, we started communication with the affected teams. The announcement was made as soon as we could confirm the details and as fast as we could type. No financial or payment information was accessed or compromised in this attack. Since the compromised system was first discovered, we have been working 24 hours a day to methodically examine, rebuild and test each component of our system to ensure it is safe. We are collaborating with outside experts to cross-check assumptions and ensure that we are meticulous in our approach. In addition we have notified law enforcement of this illegal intrusion. As part of our investigation we detected suspicious activity affecting a very small number of Slack accounts. We have notified the individual users and team owners who we believe were impacted and are sharing details with their security teams. Unless you have been contacted by us directly about a password reset or been advised of suspicious activity in your team’s account, all the information you need is in this blog post. We are committed to continual improvement of both internal security practices and development of features that help you take control of your own and your team’s security on Slack. In addition to the recent changes to our infrastructure, we have also just released two new features you should know about: Two Factor Authentication (“2FA”; also known as “two step verification”), which is now available for all users/teams. Detailed instructions are available on our help site and if you are signed in, you can set it up right now on your team site. We strongly recommend that everyone use 2FA, both on Slack and everywhere else it is available. A “Password Kill Switch” for team owners, which allows for both instantaneous team-wide resetting of passwords and forced termination of all user sessions for all team members (which means that everyone is signed out of your Slack team in all apps on all devices). Team owners can find this option under the authentication tab of your team settings. For more on our security practices and policies, see https://slack.com/security. Should you have any questions, see our FAQ below or contact us at security@slack.com. Again, our most sincere apologies. We are making every effort to prevent any similar occurrence in the future. Anne Toth VP, Policy & Compliance Strategy FAQ Q: How do I reset my password? You can reset your password in your Slack profile settings. In addition, team owners and administrators can now easily reset passwords for an entire team at once using our new “password kill switch” feature. If your Slack team uses single sign-on (SSO) you do not need to reset your password as we do not store passwords for users with this feature enabled. Q: Why are you releasing Two Factor Authentication now? Why not earlier? Two Factor Authentication has been in development for the last few months. It is a complicated change which requires additional support resources, administrative capabilities, changes to all applications, mobile and desktop, and extensive testing. We were about a week from release, with just a few small UI tweaks to simplify and clarify the usage experience. We have decided to release it immediately, despite the remaining bits of clunky-ness: the feature works and it does provide a significant new level of protection against unauthorized access to your Slack account. We will be improving this feature in future releases but the feature functionality is what is most important right now. Q. What are you doing to prevent additional breaches? We cannot overemphasize how seriously we take this incident and the importance we place on the security of your information in the broadest sense, from internal compliance processes, audits and physical access control to continual review of our systems design and approach to technical operations. We have launched Two Factor Authentication and additional administrative security tools to help users and teams better manage the security of their own accounts. You can expect to hear more about new security initiatives and features in Slack and you can count on our commitment to the ongoing investment in and prioritization of Slack’s security. Q: Were my messages taken/read/accessed? If you have not been explicitly informed by us in a separate communication that we detected suspicious activity involving your Slack account, we are very confident that there was no unauthorized access to any of your team data (such as messages or files). Q: Who can I reach if I have additional questions? If you have questions outside of those covered here please contact security@slack.com. Sursa: slackhq.com
  20. nedo

    Cerere !

    TC, fara copilarisme de genul arhive de flood, cereri dupa "root de flood" si alte tampenii.
  21. Exista deja un "abonament anual", ii spune licenta, si exista de ani buni. De spionat oricum suntem spionati de ani buni, direct, sau indirect.
  22. Salut. Mai jos va prezint o coada, scrisa de mine, generica, ce poate fi folosita cu orice fel de tip de variabila. La ce e utilizata? Coada se foloseste intr-un program ce foloseste un model tip producator/consumator(i). In aceasta coada puteti adauga instante ale tipului de variabila ales(printr-un thread producator), iar unul sau mai multe threaduri consumatoare le pot scoate din coada fara a avea probleme cu deadlock, livelock, sau race condition. In exemplul de mai jos, voi folosi 2 clase, una producator si una consumator, si un numar de 5 threaduri, 1 producator si 4 consumatori. Modelul de baza al acestei cozi este inspirat de catre coada prioritara gasita in sample-ul wxwidgets. Aceasta implementare se foloseste doar de facilitati c++, ne avand dependinte, totusi pentru a o putea utiliza aveti nevoie de un compilator modern ce suporta standardul c++11, si la compilare aveti nevoie sa utilizati flag-ul -std=c++11(pentru gcc sau clang). queue.h template <class T> class queue_priority { public: enum class priorities{P_HIGH, P_NORMAL, P_LOW}; queue_priority(unsigned long max_size); queue_priority(); queue_priority(const queue_priority& other); queue_priority& operator=(const queue_priority& other); bool pop(T& t); bool push(priorities p, T& t); void suspend(); void resume(); private: std::multimap<priorities, T> m_map; std::mutex m_mutex_action; std::mutex m_mutex_cv_suspend; std::condition_variable m_cv_suspend; std::atomic_bool m_bool_suspend; std::atomic_bool m_bool_full; std::atomic_bool m_bool_empty; std::atomic<unsigned int> m_nr_current_items; size_t MAX; }; queue.cpp template <class T> queue_priority<T>::queue_priority() : MAX(200) { m_bool_full = false; m_bool_suspend = false; m_bool_empty = true; m_nr_current_items = 0; } template <class T> queue_priority<T>::queue_priority(size_t max_size) : MAX(max_size) { m_bool_full = false; m_bool_suspend = false; m_bool_empty = true; m_nr_current_items = 0; } template <class T> queue_priority<T>::queue_priority(const queue_priority& other) : MAX(other.MAX) { m_map = std::move(other.m_map); m_bool_full = other.m_bool_full.load(); m_bool_empty = other.m_bool_empty.load(); m_bool_suspend = other.m_bool_suspend.load(); m_nr_current_items = other.m_nr_current_items.load(); } template <class T> queue_priority<T>& queue_priority<T>::operator=(const queue_priority<T>& other) { m_map = other.m_map; m_bool_full = other.m_bool_full.load(); m_bool_empty = other.m_bool_empty.load(); m_bool_suspend = other.m_bool_suspend.load(); m_nr_current_items = other.m_nr_current_items.load(); return *this; } template <class T> bool queue_priority<T>::pop(T& t) { // verificam daca se doreste suspendarea cozi si asteptam pana primim mesajul sa repornim coada if(m_bool_suspend.load()) { std::unique_lock<std::mutex> suspendLock(m_mutex_action); m_cv_suspend.wait(suspendLock, [this] {return m_bool_suspend.load();}); } // inchidem mutex-ul ce protezeaza datele interne(map-ul cu variabila noastra)> std::lock_guard<std::mutex> lock(m_mutex_action); // fiind intr-un pop, inainte sa extragem un element din coada, verificam daca aceasta e goala si returnam daca este if(m_bool_empty.load()) { return false; } t = m_map.begin()->second; m_map.erase(m_map.begin()); bool expected = true; // in cazul in care coada era plina, semnalizam ca aceasta nu mai este while(!m_bool_full.compare_exchange_weak(expected, false)) {} // daca a devenit goala, semnalizam acest lucru if(m_map.empty()) { expected = false; while(m_bool_empty.compare_exchange_weak(expected, true)) {} } return true; } template <class T> bool queue_priority<T>::push(priorities p, T& t) { // verificam daca se doreste suspendarea cozi si asteptam pana primim mesajul sa repornim coada if(m_bool_suspend.load()) { std::unique_lock<std::mutex> suspendLock(m_mutex_action); m_cv_suspend.wait(suspendLock, [this] {return m_bool_suspend.load();}); } // inchidem mutex-ul ce protezeaza datele interne(map-ul cu variabila noastra)> std::lock_guard<std::mutex> lock(m_mutex_action); // fiind un push, verificam daca coada este plina, iar daca este, iesim. if(m_bool_full.load()) { return false; } // inseram datele m_map.insert(std::make_pair(p, std::move(t))); // semnalizam faptul ca am introdus element => coada nu mai este goala bool expected = true; while(m_bool_empty.compare_exchange_weak(expected, false)) {} // daca am umplut coada, semnalizam asta. if(m_map.size() == MAX) { expected = false; while(m_bool_full.compare_exchange_weak(expected, true)) {} } return true; } template <class T> void queue_priority<T>::suspend() { m_bool_suspend = true; } template <class T> void queue_priority<T>::resume() { m_bool_suspend = false; m_cv_suspend.notify_all(); } Cam asta ar fi codul clasei. Mai jos o sa va atasez un exemplu complet. In finalul fisierului queue.cpp veti gasi o instantiere a clasei priority_queue<Job>; Este necesara deoarece atunci cand folosesti templates apare o problema. La compilare fisierele se compileaza separat, iar atunci cand queue.cpp este compilat el nu stie de existenta instantei priority_queue<Job>, iar cand veti incerca sa folositi clasa, veti primi o eroare. Mai multe detalii despre asta gasiti in acest raspuns. Mai jos aveti codul unui proiect complet. 3 fisiere, main.cpp, queue.h, queue.cpp Programelul va citi un fisier ce contine pe cate un rand numere de la 1 la x(generatis i voi fisierul, nu il mai adaug deoarece este mare) - eu am folosit 10000, citeste numarul si il pune in coada. Consumatori il extrag din coada si verifica daca este par sau impar si il introduc in fisierul potrivit. Tineti cont totusi ca modelul ales de mine(1 producator si 4 consumatori) nu este cel mai eficient. Eficientizarea acestui model se face prin teste si masuratori repetate, acesta e utilizat doar pentru a exemplifica utilizarea acestei cozi. main.cpp #include "queue.h" #include <memory> using namespace std; int main() { for(int i = 0; i < 1000;i++) { cout << "looping for " << i << " time. " << endl; queue_priority<Job>* cj = new queue_priority<Job>(); Producator prod(cj, std::string("intrare.txt")); // fisierul cu numerele auto sp_par = std::make_shared<std::ofstream>("iesire_par.txt"); // fisier de salvare pare auto sp_impar = std::make_shared<std::ofstream>("iesire_impar.txt"); // fisier de salvare impare Consummer con1(cj, sp_par, sp_impar); Consummer con2(cj, sp_par, sp_impar); Consummer con3(cj, sp_par, sp_impar); Consummer con4(cj, sp_par, sp_impar); std::thread trd_con1(std::ref(con1)); std::thread trd_con2(std::ref(con2)); //std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::thread trd_con3(std::ref(con3)); std::thread trd_con4(std::ref(con4)); std::thread trd_prod(std::ref(prod)); trd_con1.join(); trd_con2.join(); trd_prod.join(); trd_con3.join(); trd_con4.join(); delete cj; } cout << "Apasati enter pentru a iesi."; cin.get(); // tinem fereastra deschisa return 0; } queue.h #ifndef QUEUE_H_INCLUDED #define QUEUE_H_INCLUDED #include <iostream> #include <fstream> #include <map> #include <vector> #include <thread> #include <mutex> #include <atomic> #include <condition_variable> #include <cstdlib> // static specifica faptul ca acesti mutexi sa fie folositi doar in aceasta unitate translationala // adica sa nu fie vizibili in fisierele ce includ acest header static std::mutex m_mutex_par; // protezeasa fisierul de iesire numere pare static std::mutex m_mutex_impar; // protejeaza fisierul de iesire numere impare class Data { public: Data(std::string data); Data() = default; ~Data() = default; Data& operator=(const Data& other); std::string GetData(); private: std::string m_data; }; class Job { public: enum class commands{J_COM_THREAD_EXIT, J_COM_THREAD_JOB}; Job(Data data, commands cmd = commands::J_COM_THREAD_JOB); Job() = default; ~Job() = default; Job& operator=(const Job& other); Data GetData(); commands GetCommand(); private: Data m_data; commands m_cmd; }; template <class T> class queue_priority { public: enum class priorities{P_HIGH, P_NORMAL, P_LOW}; queue_priority(unsigned long max_size); queue_priority(); queue_priority(const queue_priority& other); queue_priority& operator=(const queue_priority& other); bool pop(T& t); bool push(priorities p, T& t); void suspend(); void resume(); private: std::multimap<priorities, T> m_map; std::mutex m_mutex_action; std::mutex m_mutex_cv_suspend; std::condition_variable m_cv_suspend; std::atomic_bool m_bool_suspend; std::atomic_bool m_bool_full; std::atomic_bool m_bool_empty; size_t MAX; }; class Producator { public: Producator(queue_priority<Job>* cj, std::string inputFile); Producator() = default; ~Producator() = default; void operator()(); private: queue_priority<Job>* mp_queue; std::string m_in_file_path; }; class Consummer { public: Consummer(queue_priority<Job>* cj, std::shared_ptr<std::ofstream> par, std::shared_ptr<std::ofstream> impar); Consummer() = default; ~Consummer() = default; Consummer& operator=(const Consummer& other); void operator()(); private: queue_priority<Job>* mp_queue; std::shared_ptr<std::ofstream> m_par; std::shared_ptr<std::ofstream> m_impar; }; #endif // QUEUE_H_INCLUDED queue.cpp #include "queue.h" Data::Data(std::string data) : m_data(data) { } Data& Data::operator=(const Data& other) { m_data = other.m_data; return *this; } std::string Data::GetData() { return m_data; } Job::Job(Data data, commands cmd) : m_data(data), m_cmd(cmd) { } Job& Job::operator=(const Job& other) { m_data = other.m_data; m_cmd = other.m_cmd; return *this; } Data Job::GetData() { return m_data; } Job::commands Job::GetCommand() { return m_cmd; } Producator::Producator(queue_priority<Job>* cj, std::string inputFile) : mp_queue(cj), m_in_file_path(inputFile) { } void Producator::operator()() { if(mp_queue == nullptr) { return; } std::ifstream fIn(m_in_file_path.c_str()); if(!fIn.is_open()) { mutex_cout.lock(); std::cout << "Nu am putut deschide fisierul de intrare." << std::endl; mutex_cout.unlock(); // aveti grija la iesire, asigurati-va ca joburile pentru iesire chiar au fost introduse // folositi while loop-ul de mai jos pentru a va asigura ca un job critic chiar a fost introdus Job jExit(Data(""), Job::commands::J_COM_THREAD_EXIT); for(size_t i = 0; i < 4;i++) { while(!mp_queue->push(queue_priority<Job>::priorities:_LOW, jExit)) { std::this_thread::yield(); } } return; } std::string line; while(std::getline(fIn, line)) { if(line.empty()) { mutex_cout.lock(); std::cout << "Am gasit o linie goala." << std::endl; mutex_cout.unlock(); continue; } Job jb = Job(Data(line)); unsigned counter = 0; while(!mp_queue->push(queue_priority<Job>::priorities:_NORMAL, jb)) { std::this_thread::yield(); } } // aveti grija la iesire, asigurati-va ca joburile pentru iesire chiar au fost introduse // folositi while loop-ul de mai jos pentru a va asigura ca un job critic chiar a fost introdus Job jExit(Data(""), Job::commands::J_COM_THREAD_EXIT); for(size_t i = 0; i < 4;i++) { while(!mp_queue->push(queue_priority<Job>::priorities:_LOW, jExit)) { std::this_thread::yield(); } } } Consummer::Consummer(queue_priority<Job>* cj, std::shared_ptr<std::ofstream> par, std::shared_ptr<std::ofstream> impar) : mp_queue(cj), m_par(par), m_impar(impar) { } Consummer& Consummer::operator=(const Consummer& other) { mp_queue = other.mp_queue; m_par = other.m_par; m_impar = other.m_impar; return *this; } void Consummer::operator()() { if(mp_queue == nullptr) { return; } Job jb; while(!mp_queue->pop(jb)) { std::this_thread::yield(); } while(jb.GetCommand() != Job::commands::J_COM_THREAD_EXIT) { Data data = jb.GetData(); int nr = atoi(data.GetData().c_str()); if(nr == 0) { mutex_cout.lock(); std::cout << "Am primit cifra 0, continut linie nedefinit ." << std::endl; mutex_cout.unlock(); continue; } if((nr % 2) == 0) { m_mutex_par.lock(); *m_par << nr << std::endl; m_mutex_par.unlock(); } else { m_mutex_impar.lock(); *m_impar << nr << std::endl; m_mutex_impar.unlock(); } //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // sleeping to simulate some work while(!mp_queue->pop(jb)) { std::this_thread::yield(); } } } template <class T> queue_priority<T>::queue_priority() : MAX(200) { m_bool_full = false; m_bool_suspend = false; m_bool_empty = true; } template <class T> queue_priority<T>::queue_priority(size_t max_size) : MAX(max_size) { m_bool_full = false; m_bool_suspend = false; m_bool_empty = true; } template <class T> queue_priority<T>::queue_priority(const queue_priority& other) : MAX(other.MAX) { m_map = std::move(other.m_map); m_bool_full = other.m_bool_full.load(); m_bool_empty = other.m_bool_empty.load(); m_bool_suspend = other.m_bool_suspend.load(); } template <class T> queue_priority<T>& queue_priority<T>::operator=(const queue_priority<T>& other) { m_map = other.m_map; m_bool_full = other.m_bool_full.load(); m_bool_empty = other.m_bool_empty.load(); m_bool_suspend = other.m_bool_suspend.load(); return *this; } template <class T> bool queue_priority<T>::pop(T& t) { // verificam daca se doreste suspendarea cozi si asteptam pana primim mesajul sa repornim coada if(m_bool_suspend.load()) { std::unique_lock<std::mutex> suspendLock(m_mutex_action); m_cv_suspend.wait(suspendLock, [this] {return m_bool_suspend.load();}); } // inchidem mutex-ul ce protezeaza datele interne(map-ul cu variabila noastra)> std::lock_guard<std::mutex> lock(m_mutex_action); // fiind intr-un pop, inainte sa extragem un element din coada, verificam daca aceasta e goala si returnam daca este if(m_bool_empty.load()) { return false; } t = m_map.begin()->second; m_map.erase(m_map.begin()); bool expected = true; // in cazul in care coada era plina, semnalizam ca aceasta nu mai este while(!m_bool_full.compare_exchange_weak(expected, false)) {} // daca a devenit goala, semnalizam acest lucru if(m_map.empty()) { expected = false; while(m_bool_empty.compare_exchange_weak(expected, true)) {} } return true; } template <class T> bool queue_priority<T>::push(priorities p, T& t) { // verificam daca se doreste suspendarea cozi si asteptam pana primim mesajul sa repornim coada if(m_bool_suspend.load()) { std::unique_lock<std::mutex> suspendLock(m_mutex_action); m_cv_suspend.wait(suspendLock, [this] {return m_bool_suspend.load();}); } // inchidem mutex-ul ce protezeaza datele interne(map-ul cu variabila noastra)> std::lock_guard<std::mutex> lock(m_mutex_action); // fiind un push, verificam daca coada este plina, iar daca este, iesim. if(m_bool_full.load()) { return false; } // inseram datele m_map.insert(std::make_pair(p, std::move(t))); // semnalizam faptul ca am introdus element => coada nu mai este goala bool expected = true; while(m_bool_empty.compare_exchange_weak(expected, false)) {} // daca am umplut coada, semnalizam asta. if(m_map.size() == MAX) { expected = false; while(m_bool_full.compare_exchange_weak(expected, true)) {} } return true; } template <class T> void queue_priority<T>::suspend() { m_bool_suspend = true; } template <class T> void queue_priority<T>::resume() { m_bool_suspend = false; m_cv_suspend.notify_all(); } template class queue_priority<Job>; // instantiem clasa noastra, detalii mai sus. Un avertisment. Aveti grija atunci cand producatorul termina treaba, fiti siguri ca ati introdus numarul corect de joburi pentru iesire, altfel daca folositi threaduri joinable o sa va treziti ca la final asteptati la infinit dupa ele.(am pus un avertisment in cod) Daca aveti intrebari le astept.
  23. Detaliaza te rog. In ce sens extragerea? Afisarea doar consoanelor din sir? Notarea consoanelor existente in sir? E simplu, pentru stocarea consoanelor intr-un alt string faci asa: Intr-un string pui consoanele. In alt string pui sirul tau. Un al 3-lea sir va stoca consoanele. Pentru fiecare caracter din sir, treci prin string-ul cu consoanele. Cand ai gasit o consoana, o introduci in al 3-lea string, si mergi la urmatorul caracter din sir.
×
×
  • Create New...