Кресты / Говнокод #17725 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
#include <ppl.h>
#include <windows.h>
#include <ppltasks.h>
#include <iostream>
#include <vector>

using namespace Concurrency;
using namespace std;

CRITICAL_SECTION cs6;

int main(int argc, char* argv[])
{
	size_t concurentThreadsSupported = std::thread::hardware_concurrency();
	cout << concurentThreadsSupported << endl;
	//deadlock hazard increased with concurentThreadsSupported decreasing

	size_t taskAmountForWasteVirtualCores = concurentThreadsSupported - 1;//must be equal to (virtual processor thread amount from Concurrency::IResourceManager) - 1
	vector<task<void>> t;
	for (size_t i = 0; i<taskAmountForWasteVirtualCores; ++i)
		t.push_back(create_task([]{
			Sleep(INFINITE);//some very long IO operation or deadlocked by EnterCriticalSection or sql transaction or other
		}));
	Sleep(1000);
    cout << "another way:" << endl;
    InitializeCriticalSection(&cs6);
    auto locker = create_task([]{
        cout << "locker" << endl;
        EnterCriticalSection(&cs6);//same as begin sql transaction
        cout << "locker entered cs 6" << endl;
        Concurrency::wait(500);//Deadlock by any concurrency context switching directly or indirectly by std or MFC (events, mutex, etc)
        cout << "locker played" << endl;
        LeaveCriticalSection(&cs6);//same as end sql transaction
        cout << "~locker ok" << endl;
    });
    auto locked = create_task([]{
        cout << "locked" << endl;
        EnterCriticalSection(&cs6);//same as begin sql transaction
        cout << "locked entered cs 6" << endl;
        Concurrency::wait(500);
        cout << "locked played" << endl;
        LeaveCriticalSection(&cs6);//same as end sql transaction
        cout << "~locked ok" << endl;
    });
	Sleep(1000);
	cout << "FAIL" << endl;
	return 0;
}

Нашел дидлок)
http://rextester.com/KHC72232
http://rextester.com/EMG65441

Запостил: laMer007 laMer007, (Updated )

Комментарии (11) RSS

  • #include <ppl.h>
    #include <windows.h>
    #include <ppltasks.h>
    #include <iostream>
    #include <vector>
    
    using namespace Concurrency;
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	size_t concurentThreadsSupported = std::thread::hardware_concurrency();
    	cout << concurentThreadsSupported << endl;
    	//deadlock hazard increased with concurentThreadsSupported decreasing
    
    	size_t taskAmountForWasteVirtualCores = concurentThreadsSupported - 1;//must be equal to (virtual processor thread amount from Concurrency::IResourceManager) - 1
    	vector<task<void>> t;
    	for (size_t i = 0; i<taskAmountForWasteVirtualCores; ++i)
    		t.push_back(create_task([]{
    			Sleep(INFINITE);//some very long IO operation or deadlocked by EnterCriticalSection or sql transaction or other
    		}));
    	Sleep(1000);
        HANDLE event = CreateEventA(nullptr, 1, 0, "I am bad guy");
        auto locked = create_task([event]{
            cout << "unlocker" << endl;
            Concurrency::wait(100);
            SetEvent(event);
            cout << "~unlocker ok" << endl;
        });
        auto locker = create_task([event]{
            cout << "locked" << endl;
            WaitForSingleObject(event, INFINITE);
            cout << "~locked ok" << endl;
        });
    	Sleep(1000);
    	cout << "FAIL" << endl;
    	return 0;
    }
    Что там майкрософт то курило? Как таких локов избежать, если кучу потоков ждет завершения sql транзакции как в нульпосте (для простоты примера критические секции юзаем)?
    Ответить
    • Именно из-за второго и вешались все потоки в приложении. На самом деле не все, но в целом казалось что все. Просто те что не вешались в данный момент не выполняли работы.
      Ответить
  • Если кому интересно, то проблему собираюсь решить так:
    http://rextester.com/AKZL36928
    class scoped_oversubcription_token
    {
    public:
    	scoped_oversubcription_token()
    	{
    		Concurrency::Context::CurrentContext()->Oversubscribe(true);
    	}
    	~scoped_oversubcription_token()
    	{
    		Concurrency::Context::CurrentContext()->Oversubscribe(false);
    	}
    };
    using namespace Concurrency;
    using namespace std;
    CRITICAL_SECTION cs6;
    int main(int argc, char* argv[])
    {
    	size_t concurentThreadsSupported = std::thread::hardware_concurrency();
    	cout << concurentThreadsSupported << endl;
    	size_t taskAmountForWasteVirtualCores = concurentThreadsSupported - 1;//must be equal to (virtual processor thread amount from Concurrency::IResourceManager) - 1
    	vector<task<void>> t;
    	for (size_t i = 0; i<taskAmountForWasteVirtualCores; ++i)
    		t.push_back(create_task([]{
                scoped_oversubcription_token t;
    			Sleep(INFINITE);//some very long IO operation or deadlocked by EnterCriticalSection or sql transaction or other
    		}));
    	Sleep(1000);
    Ответить
    • InitializeCriticalSection(&cs6);
          auto locker = create_task([]{
              scoped_oversubcription_token t;
              cout << "locker" << endl;
              EnterCriticalSection(&cs6);//same as begin sql transaction
              cout << "locker entered cs 6" << endl;
              Concurrency::wait(500);//Deadlock by any concurrency context switching directly or indirectly by std or MFC (events, mutex, etc)
              cout << "locker played" << endl;
              LeaveCriticalSection(&cs6);//same as end sql transaction
              cout << "~locker ok" << endl;
          });
          auto locked = create_task([]{
              scoped_oversubcription_token t;
              cout << "locked" << endl;
              EnterCriticalSection(&cs6);//same as begin sql transaction
              cout << "locked entered cs 6" << endl;
              Concurrency::wait(500);
              cout << "locked played" << endl;
              LeaveCriticalSection(&cs6);//same as end sql transaction
              cout << "~locked ok" << endl;
          });
      	Sleep(1000);
      	cout << "OK" << endl;
      	return 0;
      }
      Ответить
  • КЛИЕНТСКИЕ БАЗЫ для всех кто много продает (для юрлиц и физлиц)! Узнайте подробнее! Skype: prodawez390 Email: prodawez393@gmail.com Whatsapp: +79139230330 Viber: +79139230330 Telegram: +79139230330
    Ответить

Добавить комментарий

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8