Меню

R6010 abort has been called ошибка

434 / 299 / 82

Регистрация: 11.12.2010

Сообщений: 1,209

1

01.04.2013, 14:27. Показов 22478. Ответов 10


Написал программу которая перемножает 2 очень больших матрицы.
На мелких она работает. То есть 10000 на 10000 умножает без проблем.
Однако 15000×15000 и выше уже выбивают

: R6010 — abort() has been called

Грешил на тип. Так как матрицы типа int сменил на long ошибка осталась.



0



🙂

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

01.04.2013, 14:31

2

Kill100, код в студию. А вообще подобная ошибка встречалась при отсутствии конфига в нужном каталоге.



1



5224 / 3196 / 362

Регистрация: 12.12.2009

Сообщений: 8,101

Записей в блоге: 2

01.04.2013, 14:35

3

15000 * 15000 = 225 000 000
225 000 000 * 4(sizeof(int)) = 900 000 000 = ~900 MB
900 * 2 (матрицы) = ~1.8 GB

сколько RAM на машине?



1



434 / 299 / 82

Регистрация: 11.12.2010

Сообщений: 1,209

01.04.2013, 14:43

 [ТС]

4

Цитата
Сообщение от Kastaneda
Посмотреть сообщение

900 * 2 (матрицы) = ~1.8 GB
сколько RAM на машине?

16gb. Так что в этом проблемы быть не может



0



5224 / 3196 / 362

Регистрация: 12.12.2009

Сообщений: 8,101

Записей в блоге: 2

01.04.2013, 14:45

5

причин для abort() много, а дебажить пробовал?



0



434 / 299 / 82

Регистрация: 11.12.2010

Сообщений: 1,209

01.04.2013, 14:47

 [ТС]

6

Цитата
Сообщение от Tulosba
Посмотреть сообщение

Kill100, код в студию. А вообще подобная ошибка встречалась при отсутствии конфига в нужном каталоге.

Чел спс! Ты натолкнул меня 1 очень интересную мысль, проверил прога заработала.
В настройках проекта поставил платформу 64x. И всё пучком.



0



🙂

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

01.04.2013, 14:48

7

Не по теме:

Цитата
Сообщение от Kastaneda
Посмотреть сообщение

сколько RAM на машине?

главное чтоб на 16Гб RAM не было 32bit винды 😀

Добавлено через 26 секунд

Цитата
Сообщение от Kill100
Посмотреть сообщение

В настройках проекта поставил платформу 64x.

Ч.Т.Д



1



434 / 299 / 82

Регистрация: 11.12.2010

Сообщений: 1,209

01.04.2013, 16:54

 [ТС]

8

Рано радовался.
Теперь при построении стало писать

array_on_vector.cpp(129): warning : C6386: Переполнение буфера при записи в «Return_Vektor»: доступный для записи объем равен «len_vector_m*4» байт, однако записать можно только «8» байт.
array_on_vector.cpp(132): warning : C6385: Чтение недопустимых данных из «Return_Vektor»: доступный для чтения объем равен «len_vector_m*4» байт, однако считать можно только «8» байт.



0



🙂

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

01.04.2013, 16:57

9

Kill100, код-то покажешь или нет?



0



Kill100

434 / 299 / 82

Регистрация: 11.12.2010

Сообщений: 1,209

01.04.2013, 16:58

 [ТС]

10

А всё отбой нашел описание
http://msdn.microsoft.com/en-u… s.80).aspx

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
long* Multiply(long* vectors, long len_vector_m, long** mass, long mass_n)
{
    long* Return_Vektor = new long[len_vector_m];//а надо было mass_n
    for(long i=0; i<mass_n; i++)
    {
        Return_Vektor[i]=0;//обнуляем значение
        for (long j=0; j<len_vector_m; j++)
        {
            Return_Vektor[i]+=mass[i][j]*vectors[j];//умножение вектора на столбцы
        }
    }
    return Return_Vektor;//возвращая результат
}



0



Friday

ну и долго меня небыло…

61 / 57 / 8

Регистрация: 24.03.2013

Сообщений: 173

01.04.2013, 17:03

11

Цитата
Сообщение от Kill100
Посмотреть сообщение

А всё отбой нашел описание
http://msdn.microsoft.com/en-u… s.80).aspx

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
long* Multiply(long* vectors, long len_vector_m, long** mass, long mass_n)
{
    long* Return_Vektor = new long[len_vector_m];//а надо было mass_n
    for(long i=0; i<mass_n; i++)
    {
        Return_Vektor[i]=0;//обнуляем значение
        for (long j=0; j<len_vector_m; j++)
        {
            Return_Vektor[i]+=mass[i][j]*vectors[j];//умножение вектора на столбцы
        }
    }
    return Return_Vektor;//возвращая результат
}

попробуй long long вместо long



0



Всем доброго дня!

Использую поток от STL (std::thread) из нового стандарта (работаю с Microsoft Visual C++ Compiler Nov 2012 CTP (v120_CTP_Nov2012)). Есть класс TCPServer, содержащий в себе этот поток:

class TCPServer final : public WaitingPoint
{
  public:
    boost::asio::io_service* ioService;

  private:
    std::atomic_bool isExit;
    std::thread thread;
    boost::asio::ip::tcp::acceptor* ioAcceptor;
    std::atomic_bool isWaitingAccept;
    std::shared_ptr<ConnectionPoint> connectionAccept;

    ...
};

Затем в один из моментов я запускаю поток (то есть до этого функцию обработки я ему не указывал):

Result TCPServer::init(void)
{
  isExit=false;
  ioService=new (std::nothrow) boost::asio::io_service();
  if(!ioService) return Result::errorMemory;
  ioAcceptor=new (std::nothrow) boost::asio::ip::tcp::acceptor(*ioService);
  if(!ioAcceptor) return Result::errorMemory;
  tcp.set(ioAcceptor,nullptr);
  thread=std::thread(std::bind(&TCPServer::loop,std::static_pointer_cast<TCPServer>(shared_from_this())));
  return Result::ok;
}

Он крутит цикл:

Result TCPServer::loop(void)
{
  boost::system::error_code ec;
  while(!isExit)
  {
    ioService->run_one(ec);
    ioService->reset();
  }
  return Result::ok;
}

И когда мне уже он не нужен, я вызываю это:

void TCPServer::free(void)
{
  ioAcceptor->close();
  connectionAccept.reset();
  if(!isExit)
  {
    isExit=true;
    ioService->reset();
    ioService->stop();
    if(thread.joinable()) thread.join();
  }
}

Грубо говоря у меня есть функция release():

void WaitingPoint::release(void)
{
  if(isRemoved) return;
  isRemoved=true;
  mConnectionPoints.lock();
  size_t len=vConnectionPoints.size();
  for(size_t i=0;i<len;i++)
  {
    auto& item=vConnectionPoints[i];
    item->isRemoved=true;
    item->free();
  }
  vConnectionPoints.clear();
  mConnectionPoints.unlock();
  std::shared_ptr<WaitingPoint> p(shared_from_this());
  Core::instance->freeWaitingPoint(this);
  free();
}

Вызовом которой я удаляю сервер. Делаю я это вот так:

void release(void)
{
  if(waitingPoint) waitingPoint->release();
  while(true);
  if(connectionPoint) connectionPoint->release();
  if(core) core->release();
  std::cout<<std::endl<<"Press Enter for exit...";
  std::cin.get();
}

Тут я намеренно зациклил программу. В общем после выполнения задуманного мной сценария
и дохода до бесконечного цикла, программа в какой-то момент (уже вися основным потоком в бесконечном цикле) рушится с сообщением:

И останавливается вот тут:

То есть проблема с потоком. В чём может быть ошибка и как её исправить?

  • Изменено

    26 января 2013 г. 11:10

I am trying to generate QWTspectrogram using a file. there are 500 binary files to show an annimation with a slider in UI. the program works fine but sometimes it gives «debug error r6010 abort has been called» error and crashes on any random occasion I have no idea why this shows up because it is random however it depends on the change in fnum as slider moves but not at any fixed value or time(it does not appear at stationary condition). below is the code for my program

setAlpha is changed with the change in slider of UI.

@ void Plot::setAlpha( int alpha )

{

    fnum=alpha;

    d_spectrogram->setData( new mydata(fnum,dial) );

    d_spectrogram->attach( this );

    replot();

}


class mydata: public QwtRasterData

{

    typedef signed short int sBYTE;

    char filepath[35]; 

    sBYTE *fileBuf;    

    FILE *file = NULL; 

public:



mydata(int fnum, int dial)

    {

    setInterval( Qt::XAxis, QwtInterval( 0, (area)-1 ) );

    setInterval( Qt::YAxis, QwtInterval( 0, (area)-1 ) );

    setInterval( Qt::ZAxis, QwtInterval( -dial, dial ) );



    {

         sprintf_s(filepath, "c:/mydata/dfile%d.bin", fnum);

         fopen_s(&file,filepath, "rb");

         long fileSize = getFileSizex(file);

         fileBuf = new sBYTE[fileSize];

         fread(fileBuf, fileSize, 1, file);

         fclose(file);


     }

    }

    virtual double value( double x, double y ) const

    {



    int x_pos = static_cast<int>(x);

    int y_pos = static_cast<int>(y);

    const double c =  (fileBuf[ ((x_pos)+((area-y_pos)*area))]);

    return c;

    }

}@

В приложении, которое я пишу, я использую исключения для большей части моей обработки ошибок. Я еще не определил свои собственные классы исключений, я просто сделал следующее:

namespace Mage {
typedef std::exception Exception;
}

Таким образом, мне не придется менять весь мой код, когда я позже определю свой собственный тип, который должен использовать тот же интерфейс.

Тем не менее, любое исключение вызывает сбой моего приложения. Принимая во внимание вышеприведенное определение, с чего бы это крушение?

void Mage::Root::initialize(Mage::String& p_log) {
// initialize GLFW and GLEW.
if (!glfwInit()) {
throw new Mage::Exception("failed to initialize OpenGL");
return;
} else m_GLFWInitialized = true;

Будь я удалить или оставить «новый», он все равно потерпит крах. Я что-то пропустил? Я посмотрел учебники, но они не делают меня мудрее.

Я также ловлю ошибку прямо здесь:

try {
MAGE_ROOT.initialize(Mage::String("Mage.log"));
} catch (Mage::Exception& e) {
std::cerr << e.what() << std::endl;
}

Авария, которую я получаю, это:

Debug Error!

Program: ...sual Studio 2010ProjectMage3DBinariesDebugTest.exe

R6010
- abort() has been called

(Press Retry to debug application)

1

Решение

Проблема в том, что вы не ловите свое исключение.

Я не знал, что ты должен поймать исключение (из комментариев)

Да, ты должен. Если вы не поймали выброшенное исключение, std::terminate() будет называться. Это предполагаемое поведение: существуют исключения, которые не позволяют программистам забывая об обработке ошибок.

Это сказал, я предлагаю:

  • метание по значению;
  • ловить по ссылке

Например:

void foo()
{
// ...
throw std::logic_error("Error!");
//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
//    Throw by value (std::logic_error derives from std::exception)
// ...
}

void bar()
{
try
{
// ...
foo();
// ...
}
catch (std::exception& e)
^^^^^^^^^^^^^^^
//     Catch by reference
{
std::cout << e.what(); // For instance...
}
}

ОБНОВИТЬ:

Что касается кода, который вы разместили, вы бросаете указатель и ловить ссылка. Обработчик не будет совпадать. И поскольку нет другого подходящего обработчика, std::terminate() будет называться.

Вместо этого вы должны выбросить исключение по значению:

throw Mage::Exception("failed to initialize OpenGL");

И если код, который вы разместили, действительно тот, который вы используете, вы увидите, что управление передается вашему обработчику.

11

Другие решения

Основываясь на сообщении об ошибке, вы используете Visual Studio (2010) для вашего проекта. Если вы не заключите свой бросок в блок try / catch, он будет «проплывать через крышу» и будет «обрабатываться» средой выполнения C ++, что означает вызов abort (). Вы, вероятно, хотите что-то подобное выше в стеке вызовов:

try
{
SomeFunctionThatUltimatelyThrows();
}
catch(Exception & e)
{
// .. handle error - log, resume, exit, whatever
}

Обратите внимание также на совет Скотта Мейерса всегда отлавливать исключения по ссылке. «Исключение»: если вы используете исключения MFC CExceptions, вы хотите перехватить указатель и вызвать метод Delete для самоуничтожения исключений на основе кучи.

Основываясь на ваших изменениях, вы можете иметь несоответствие между броском «по указателю» и отловом «по ссылке». Если вы решили это и по-прежнему не выполняете свой блок catch, вы можете попробовать отладить вызов abort () с помощью CRT SetAbortHandler, чтобы установить собственную функцию прерывания. Это может просто включить в существующую, но даст возможность установить точку останова и проверить стек вызовов, чтобы увидеть, что происходит не так.

2

C ++ try-catch-throw логика для чайников. Обратите внимание, что это НЕ охватывает RAII / размещение / уничтожение на основе стека.

  • Когда вы выбрасываете исключение, исключение называется «распространяющимся». Он распространяется вверх по стеку вызовов до тех пор, пока не найдет первый обработчик, который сможет его обработать (чтобы он был перехвачен), или пока он не достигнет корня стека вызовов.
    • Если он перехвачен, выполнение продолжается с того момента, когда перехвачено исключение. Исключение уничтожается в конце блока catch.
    • Если он находит корень, он вызывает std :: unhandled_exception, который обычно вызывает std :: terminate, который обычно вызывает abort (). Короче говоря, все выпало как можно скорее.
  • Если вы генерируете исключение во время распространения исключения, у вас будет по два одновременно. Java и C # имеют хитроумные способы справиться с этим, но это никогда не должно происходить в первую очередь — нет обработчика исключений, который логически собирается обрабатывать комбинации исключений. Не выбрасывайте исключения, пока одно из них распространяется. Это правило не слишком сложно соблюдать, даже если вы не используете std :: uncaught_exception (), чего не следует делать.
  • При разматывании стека / распространении исключения все объекты, найденные в стеке, уничтожаются. Эти деструкторы никогда не должны выдавать исключение — в конце концов, когда уничтожение объекта «не удается», что еще вы будете делать после того, как деструктор его исправит?
  • Всегда бросать по значению, ловить по ссылке. Если вы бросите & поймать по указателю, вы, скорее всего, что-то утечет, что невозможно по ссылке. Если вы поймете по значению, вы отрежете свои производные типы исключений. Поймать по ссылке.
  • В корне вашего программного обеспечения, включить всеобъемлющее — catch(...), Это не позволяет вам узнать, что именно вы поймали, но, по крайней мере, вы можете безопасно потерпеть крах. Делайте это также, когда вызываемый код может выбросить «что-то», чего вы не знаете.

1

I’ve got a console program which essentially automates a large number of commandline apps, and to implement ghetto threading (because getting into real threading is a bit above my head), I’m using system() to execute psexec (in detached mode), calling the app, within a while loop. obviously, this can cause problems due to slower programs stacking up. during the initial write, this was not a problem (since the program execution would slow down when all cores were saturated), but now that I’m using the -belownormal switch in psexec, the program will continue to call new instances and it can cause crashes.

to control this, I’ve used pslist in php for a similar program, and was using that for a while, but due to the limits of my c++ knowledge, using pipes isn’t really useful, and so I made a little function that counts the number of active threads with a given name, and just stay in a while loop as long as the number of active threads is too high. unfortunately, it makes the program crash with the «R6010-abort() has been called» error. to be clear, it worked without these strange crashes before I implemented the function to keep track of how many threads were running.

applicable section of code is here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned int ci(std::wstring name){
	DWORD procs[1024],sizeret,sizeret1;
	TCHAR procnameo[MAX_PATH];
	HANDLE hproc;
	HMODULE hmod;
	unsigned int loop,count=0;
	std::wstring procname;
	EnumProcesses(procs,sizeof(procs),&sizeret);
	for(loop=0;loop<sizeret/sizeof(DWORD);loop++){
		hproc=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,procs[loop]);
		EnumProcessModules(hproc,&hmod,sizeof(hmod),&sizeret1);
		GetModuleBaseName(hproc,hmod,procnameo,sizeof(procnameo)/sizeof(TCHAR));
		procname.assign(procnameo);
		if(procname.find(name)<=1000000)count++;
		CloseHandle(hproc);
	}return count;
}

and the function is called via: search.assign(L"convert");while(ci(search)>16){Sleep(100);}

yes, I realize that my code is horrible.

anyways, any help would be much appreciated.

please note that when debugging, it does not crash at the same place, so I can’t figure out the problem from that.

EDIT:

cleaned it up to make it more readable. when i say it doesn’t crash at the same place, i mean it crashes like 300 lines later, and with a completely different error.

Last edited on

Learning threading has got to be easier than what you’re doing.

You really should write one statement per line. It’s conventional, readable and the debugger works on lines, not statements.

fixed the code to be more readable. the reason this was easier than learning threading is that i was able to find a tutorial with a code snippet that printed out all running processes, and simply adapt it to this. yes, I know that this means I don’t *learn* as much, but I’m not a student or (obviously) professional programmer; I just occasionally write a little code on the side when I need something I can’t find anywhere.

I *am* looking into threading, at your suggestion, but after 6 hours, I haven’t really gotten anywhere. I’ve opened a thread regarding that, but still consider this one open. I don’t care how it gets done, all I really want is to be able to run 8 concurrent processes, wait for one to finish, then add another one, till i’ve processed everything I need to run.

as mentioned before, this is essentially a port (and slight expansion) of a php project I wrote earlier, and in php it was simple to accomplish because exec() automatically returns the output and not just the return code. i could thus use pslist to accomplish my goal (by searching the returned string for instances of the program name). I looked into trying to do the same in c++, but it was WAY over my head, and the only other option — piping the output to a file thru dos, then reading the file in c++ and parsing it — adds a large amount of overhead when executed every tenth of a second or so.

Last edited on

I suggest Boost::threads, they are very easy to use, open source and you can probably get a simple multithreaded example running today. You can also create thread pools based on the available hardware running the software through…

This is just a suggestion and can be omitted if you know you only want x number of threads.
boost::thread::hardware_concurrency() * 2; //where 2 is the number of thread you want to spawn per core

Starting a thread…

1
2
3
4
5
6
7
8
9
10
11
12

//Start: some method in MyClass, implementation below.
//m_mythread: member variable of MyClass of type boost::thread.
//WokerThread: a member function of MyClass, has the implementation for the work to do.

bool MyClass::Start()
{
	m_mythread = boost::thread(boost::bind(&MyClass::WokerThread, this));
	return true;
}

//This is all that is required to start a thread using boost. 

Stopping the thread (called from the deconstructor for the class in my case).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool MyClass::Stop()
{
   if(m_mythread .joinable())
  {
     m_mythread .join();
     return true;
  }
  return false;
}

void MyClass::WokerThread()
{
   //Do stuff...
}


I’ve left out condition state variables and what not to make this easier to read, and you do not need state variables depending on your work and implementation.

Last edited on

i may just be missing something (like an include, or that I’m supposed to replace it with something), but after copypasta:

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
#include <iostream>
#include <string>
#include <boost/thread.hpp>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

void MyClass::Worker()
{
   //Do stuff...
}

bool MyClass::Start()
{
	m_mythread = boost::thread(boost::bind(&MyClass::Worker, this));
	return true;
}

bool MyClass::Stop()
{
   if(m_mythread .joinable())
  {
     m_mythread .join();
     return true;
  }
  return false;
}

int main(void){

	cout << "Press Enter to Continue";
cin.ignore(999,'n');
    return 0;
}

i get a bunch of compiler errors, including «1>d:imagehacktestingimagehack.cpp(9): error C2653: ‘MyClass’ : is not a class or namespace name» and «1>d:imagehacktestingimagehack.cpp(16): error C2065: ‘m_mythread’ : undeclared identifier» and «1>d:imagehacktestingimagehack.cpp(16): error C2355: ‘this’ : can only be referenced inside non-static member functions»

keep in mind that while i get some of this (like joinable and join), some is jargon (like bind) — I typically find some code, copypasta it, then twiddle with it until I can understand what’s going on.

i really appreciate the help, btw.

Yeah ok, it wasn’t meant for copy paste, I thought you knew about classes / objects etc. No worries, I created you a class for executing «tasks» using boost::threads. As it stands a task is just a string, you could use it for a file name etc. You can change it to whatever you need this is just a very simple starting point, who knows you may be able to copy your code and paste into the TaskThread and do your stuff. I don’t know what version of boost you are running however here is the code.

I also didn’t implement copy move ctor, copy move assignment, etc…

Execute.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
#include <boost/thread.hpp>
#include <string>
class Execute
{
public:
	Execute();
	virtual ~Execute();
	void TaskThread();
	bool Start(const std::string &task);
	bool Stop();
	bool IsBusy()const;
protected:
private:
	volatile bool m_busy;
	std::string m_task;
	boost::thread m_thread;
};

Execute.cpp

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
#include "Execute.h"
#include <iostream>
#include <Windows.h>

Execute::Execute() : m_busy(false)
{
}

Execute::~Execute()
{
	Stop();
}

bool Execute::Stop()
{
   if(m_thread.joinable())
  {
     m_thread.join();
     return true;
  }
   return false;
}

bool Execute::Start(const std::string &task)
{
	m_busy = true;
	m_task = task;
	
	m_thread = boost::thread(boost::bind(&Execute::TaskThread, this));
	Sleep(500);
	return true;
}

void Execute::TaskThread()
{
   //This is where you need to do your work, open file, call another batch, job w/e
  //close file etc.
	std::cout << "Inside thread " << m_task << std::endl;
	m_busy = false; //This needs to be the last thing in here
	return;
}

bool Execute::IsBusy()const
{
	//Sleep(500); can put a sleep here if you don't want to constantly poll
	//A better option would be to use condition variables for shutdown etc. but I'm keeping this simple for you.
	return m_busy;
}


There is virtually no synchronization here.
To keep this as simple as I can I left it at this, I’ll try to answer your questions time permitting. Things like I put the stop in the deconstructor, I did it there so you could use my example as is. You could not call it there, then call stop yourself…

I left the cout in there so you could mess around with it.

1
2
3
4
5
6
7
8
9
10
11

int main()
{
   { //Scope
	Execute exe, exe2, exe3;
	exe.Start("task1");
	exe2.Start("task2");
	exe3.Start("task3");
   } //Deconstruction
   return 0;
}

Last edited on

upon initial copypasta, this doesn’t seem to provide a method of limiting execution to an arbitrary number of threads at a time. I can either make a bunch of exe’s, and launch them all concurrently (which would be silly, since it’s that exact behaviour that I’m using threads to avoid ;P), or run them in batches, ie:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(void){
	unsigned int count=10,loop;
	 for(loop=0;loop<count;loop++){ //Scope
		Execute exe1, exe2, exe3,exe4,exe5,exe6,exe7,exe8;
		if(loop<count)exe1.Start("task1");loop++;
		if(loop<count)exe2.Start("task2");loop++;
		if(loop<count)exe3.Start("task3");loop++;
		if(loop<count)exe4.Start("task4");loop++;
		if(loop<count)exe5.Start("task5");loop++;
		if(loop<count)exe6.Start("task6");loop++;
		if(loop<count)exe7.Start("task7");loop++;
		if(loop<count)exe8.Start("task8");
	} //Deconstruction
	cout << "Press Enter to Continue";
cin.ignore(999,'n');
    return 0;
}

in which, it will execute 8 threads, wait till they’re all done, then execute the other 2. what I’m trying for is something where (in the case of 10 executions desired, as above) it will launch the initial 8, then as each one finishes, launch another until all 10 have been launched, ie:

enter loop->launch 1-8->4 finishes->launch 9->2 finishes->launch 10-> 1,3,5,6,7,8,9,10 finish->exit loop

ideally, the best method would be to keep track of how many threads are running and use that to control it. if i only needed to run 10 at a time, it wouldn’t be a problem, but it can easily balloon over 1000 in my program, so it becomes a huge bottleneck.

i could of course use duct tape and do something like writing a «lock» file while the thread is running, then deleting the lock when it’s done, and simply counting the number of lock files to tell how many threads are running… but this will add unnecessary overhead.

you may actually have this mechanism somewhere in the code, but I can’t see it.

again, much thanks for the help!

EDIT:

I figured out how to accomplish what i want — something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	string command("");
	bool one=false,two=false,three=false,four=false,five=false,six=false,seven=false,eight=false;
	unsigned int count=10,loop;
	loop=0;while(loop<count){
		command.assign("psexec -accepteula -belownormal optipng -zc1-3 -zm1-3 -zs1-3 -f1-3 -i0 -zw 32k "D:/testing/input/Gantz_v01c01p010{t.png-task1.png" >nul 2>&1");
		if(loop<count && one==false){one=true;boost::thread thread1(worker,&one,command);loop++;}
		command.assign("psexec -accepteula -belownormal optipng -zc1-4 -zm1-4 -zs1-3 -f1-4 -i0 -zw 32k "D:/testing/input/Gantz_v01c01p010{t.png-task1.png" >nul 2>&1");
		if(loop<count && two==false){two=true;boost::thread thread2(worker,&two,command);loop++;}
		command.assign("psexec -accepteula -belownormal optipng -zc1-5 -zm1-5 -zs0-3 -f1-5 -i0 -zw 32k "D:/testing/input/Gantz_v01c01p010{t.png-task1.png" >nul 2>&1");
		if(loop<count && three==false){three=true;boost::thread thread3(worker,&three,command);loop++;}
		command.assign("psexec -accepteula -belownormal optipng -zc1-6 -zm1-6 -zs0-3 -f0-5 -i0 -zw 32k "D:/testing/input/Gantz_v01c01p010{t.png-task1.png" >nul 2>&1");
		if(loop<count && four==false){four=true;boost::thread thread4(worker,&four,command);loop++;}
//		if(loop<count && five==false){five=true;boost::thread thread5(worker,&five,command);loop++;}
//		if(loop<count && six==false){six=true;boost::thread thread6(worker,&six,command);loop++;}
//		if(loop<count && seven==false){seven=true;boost::thread thread7(worker,&seven,command);loop++;}
//		if(loop<count && eight==false){eight=true;boost::thread thread8(worker,&eight,command);loop++;}
	}

as you can see, I’m passing the pointer to the function, and right before the function exits, it flips the bool back to false — essentially, it’s a lock file, but in ram (bool, even), so a minimal performance hit. unfortunately, it means that the number of concurrent threads is essentially hardcoded, but I can add hardware concurrency to the if statement to keep it from executing more threads than the cpu can handle. so really only the maximum number of threads is hardcoded.

much thanks clanmjc, i couldn’t have done it without you!

Last edited on

Great glad I could help. I whipped this up for you as well…

Here you go.. replace your Execute.h and .cpp with these… I’ve used depreciated things in main. This will allow you to.

1) Create a vector of commands.
2) Add those commands to a task queue
3) concurrently process the queue of tasks

The thread pool is hardcoded but can be easily changed. I’ve also included a max thread count that based on the hardware, you can add some code to use whichever is greater but right now it always uses 8.

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
#pragma once
#include <boost/thread.hpp>
#include <string>
#include <queue>

typedef boost::shared_ptr<boost::thread> SharedThreadPtr;

class Execute
{
public:
	static Execute& GetExecuter();
	virtual ~Execute();
	void TaskThread();
	bool Start();
	bool Stop();
	void AddTask(const std::string &task);
	bool IsTaskQueueEmpty();
protected:
private:
	Execute(int);
	Execute(const Execute& );
	Execute& operator=(const Execute& );
	
	int threadcount;
	int maxthreadcount;
	std::queue<std::string> m_taskqueue;

	std::vector<SharedThreadPtr> m_threads;
	
	boost::mutex mut_TaskQueue_;
};

.cpp

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
#include "Execute.h"
#include <iostream>
#include <Windows.h>

Execute::Execute(int mincount) : threadcount(mincount)
{
	maxthreadcount = boost::thread::hardware_concurrency() * 2;
}

Execute::~Execute()
{
	
}

bool Execute::Stop()
{
	for(size_t i = 0; i < m_threads.size(); ++i)
		if(m_threads[i]->joinable())
			m_threads[i]->join();

	m_threads.clear();
	return true;
}

bool Execute::Start()
{
	
	for(int i = 0; i < threadcount; ++i)
	{
		m_threads.push_back(SharedThreadPtr(new boost::thread(boost::bind(&Execute::TaskThread, this))));
	}
	return true;
}

void Execute::TaskThread()
{
	while(1)
	{
		std::string taskToProcess;
		{
			boost::lock_guard<boost::mutex> lock(mut_TaskQueue_);
			if(!m_taskqueue.empty())
			{
				taskToProcess = m_taskqueue.front();
				m_taskqueue.pop();
			}else
				break;
		}
		//Process task here...
		std::cout << "Inside thread " << taskToProcess << std::endl;
	}
	
	
}

Execute& Execute::GetExecuter()
{
	static Execute instance(8);
	return instance;
}

void Execute::AddTask(const std::string &task)
{
	boost::lock_guard<boost::mutex> lock(mut_TaskQueue_);
	m_taskqueue.push(task);
}

bool Execute::IsTaskQueueEmpty()
{
	Sleep(100);
	boost::lock_guard<boost::mutex> lock(mut_TaskQueue_);
	return m_taskqueue.empty();
}

main

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
#include "Execute.h"
#include "boost/lexical_cast.hpp"

std::vector<std::string> MakeFakeTasks();

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<std::string> tasks = MakeFakeTasks();
	
	Execute& exe = Execute::GetExecuter();
	for(std::vector<std::string>::iterator it = tasks.begin(); it != tasks.end(); ++it)
	{
		exe.AddTask(*it);
	}
	exe.Start();
	while(!exe.IsTaskQueueEmpty())
	{

	}
	exe.Stop();
	return 0;
}

std::vector<std::string> MakeFakeTasks()
{
	std::vector<std::string> fake;
	for(int i = 0; i < 10000; ++i)
	{
		std::string temp("task ");
		char buff[100];
		temp+=itoa(i,buff,10);
		fake.push_back(temp);
	}
	return fake;
}

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Qrencode dll ошибка viber
  • R5apex exe ошибка приложения 0xc0000142