Лучший способ к флагу статуса возврата и сообщению из метода в Java

Как отметил Марк Харрис, структуры могут передаваться значениями в ядра CUDA. Тем не менее, следует позаботиться о создании надлежащего деструктора, так как деструктор вызывается при выходе из ядра.

Рассмотрим следующий пример

#include <stdio.h>

#include "Utilities.cuh"

#define NUMBLOCKS  512
#define NUMTHREADS 512 * 2

/***************/
/* TEST STRUCT */
/***************/
struct Lock {

    int *d_state;

    // --- Constructor
    Lock(void) {
        int h_state = 0;                                        // --- Host side lock state initializer
        gpuErrchk(cudaMalloc((void **)&d_state, sizeof(int)));  // --- Allocate device side lock state
        gpuErrchk(cudaMemcpy(d_state, &h_state, sizeof(int), cudaMemcpyHostToDevice)); // --- Initialize device side lock state
    }

    // --- Destructor (wrong version)
    //~Lock(void) { 
    //  printf("Calling destructor\n");
    //  gpuErrchk(cudaFree(d_state)); 
    //}

    // --- Destructor (correct version)
//  __host__ __device__ ~Lock(void) {
//#if !defined(__CUDACC__)
//      gpuErrchk(cudaFree(d_state));
//#else
//
//#endif
//  }

    // --- Lock function
    __device__ void lock(void) { while (atomicCAS(d_state, 0, 1) != 0); }

    // --- Unlock function
    __device__ void unlock(void) { atomicExch(d_state, 0); }
};

/**********************************/
/* BLOCK COUNTER KERNEL WITH LOCK */
/**********************************/
__global__ void blockCounterLocked(Lock lock, int *nblocks) {

    if (threadIdx.x == 0) {
        lock.lock();
        *nblocks = *nblocks + 1;
        lock.unlock();
    }
}

/********/
/* MAIN */
/********/
int main(){

    int h_counting, *d_counting;
    Lock lock;

    gpuErrchk(cudaMalloc(&d_counting, sizeof(int)));

    // --- Locked case
    h_counting = 0;
    gpuErrchk(cudaMemcpy(d_counting, &h_counting, sizeof(int), cudaMemcpyHostToDevice));

    blockCounterLocked << <NUMBLOCKS, NUMTHREADS >> >(lock, d_counting);
    gpuErrchk(cudaPeekAtLastError());
    gpuErrchk(cudaDeviceSynchronize());

    gpuErrchk(cudaMemcpy(&h_counting, d_counting, sizeof(int), cudaMemcpyDeviceToHost));
    printf("Counting in the locked case: %i\n", h_counting);

    gpuErrchk(cudaFree(d_counting));
}

с несанкционированным деструктором ( не обращайте слишком много внимания на то, что на самом деле делает код). Если вы запустите этот код, вы получите следующий вывод

Calling destructor
Counting in the locked case: 512
Calling destructor
GPUassert: invalid device pointer D:/Project/passStructToKernel/passClassToKernel/Utilities.cu 37

. Затем два дроидатора вызывают два раза, один раз на выходе ядра и один раз на главном выходе. Сообщение об ошибке связано с тем, что, если ячейки памяти, на которые указывает d_state, освобождаются при выходе ядра, они больше не могут быть освобождены на основном выходе. Соответственно, деструктор должен отличаться для исполнения хоста и устройства. Это выполняется комментарием деструктора в приведенном выше коде.

27
задан Draemon 10 December 2008 в 15:07
поделиться

17 ответов

Возврат маленького объекта и с булевым флагом и со Строкой внутри является, вероятно, самым подобным OO способом сделать его, хотя я соглашаюсь, что это кажется излишеством для простого случая как это.

Другая альтернатива должна всегда возвращать Строку и иметь пустой указатель (или пустая строка - Вы выбираете, который), указывают на успех. Пока возвращаемые значения ясно объяснены в javadocs не должно быть никакого беспорядка.

10
ответ дан Ashley Mercer 14 October 2019 в 14:45
поделиться

Вместо того, чтобы создать специальный объект для типа возврата, я обычно просто возвращаю массив, где вся возвращенная информация хранится. Преимущество - то, что можно расширить этот массив с помощью новых элементов, не создавая новые типы и путаницу. Оборотная сторона необходимо знать точно, что должны представить элементы, когда массив возвращается из конкретного метода для парсинга ее правильно. Обычно я договариваюсь об определенной структуре, как первый элемент всегда булев успех признака, второй Строка с описанием, остальное является дополнительным. Пример:

public static void main(String[] args)
{
    Object[] result = methodReturningStatus();
    if(!(Boolean)result[0])
        System.out.println("Method return: "+ result[1]);
}

static Object[] methodReturningStatus()
{
    Object[] result = new Object[2];

    result[0] = false;
    result[1] = "Error happened";

    return result;
}
-2
ответ дан Ma99uS 14 October 2019 в 14:45
поделиться

Я выбрал бы опцию Exception в первом месте.

, Но, во втором месте, я предпочел бы метод C-стиля:

public boolean authenticate(Client client, final StringBuilder sb) {
    if (sb == null)
        throw new IllegalArgumentException();
    if (isOK()) {
        sb.append("info message");
        return true;
    } else {
        sb.append("error message");
        return false;
    }
}

Это не настолько странно, и это сделано во многих местах в платформе.

-1
ответ дан bruno conde 14 October 2019 в 14:45
поделиться

Возвратите Объект. Это позволяет Вам помещать дополнительную функциональность в Класс при необходимости в нем. Недолгие объекты в Java быстры, чтобы создать и собраться.

-1
ответ дан Javamann 14 October 2019 в 14:45
поделиться

Как насчет того, чтобы возвратить строку. Пустой или Пустой для успеха. Сообщение об ошибке в случае отказа. Самый простой, который работал бы. Однако не уверенный, если это читает хорошо.

-1
ответ дан Gishu 14 October 2019 в 14:45
поделиться

Существует много хороших ответов здесь, таким образом, я сохраню его коротким.

я думаю, что отказ пользователя аутентифицировать можно считать допустимым случаем для контролируемой исключительной ситуации. Если бы Ваш стиль программирования привилегированных обрабатывающих исключений тогда не был бы никакой причиной не сделать это. Это также удаляет, "Как возвратить несколько значений из метода, мой метод делает одну вещь, Это аутентифицирует пользователя"

, Если Вы собираетесь возвратиться, несколько значений тогда проводят 10 минут, создавая универсальный PairTuple (могут также быть больше, чем парный TripleTuple, я не повторю упомянутый выше пример), и возвратите свои значения тот путь. Я очень не хочу иметь маленькие dto объекты стиля для возврата различный несколько значений, они просто создают помехи месту.

0
ответ дан Shawn Vader 14 October 2019 в 14:45
поделиться

Успешная аутентификация должна быть "нормальным" случаем, таким образом, ошибка аутентификации является исключительным случаем.

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

if (authenticate()) {
  // normal behaviour...
}
else {
  // error case...
}

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

authenticate();
// normal behaviour...

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

if (isAuthenticated()) {
//...
}
0
ответ дан Markus 14 October 2019 в 14:45
поделиться

Это походит на общую идиому на других языках программирования, но я не могу выяснить, какой (C я предполагаю, поскольку я считал в вопросе).

Почти тот же вопрос отправляется здесь и здесь

Попытка возвратить два значения из единственной функции, может вводить в заблуждение. Но поскольку это было доказано попытками выполнения так, это может быть очень полезно также.

Определенно создание и маленький класс с результатами должны быть корректным способом продолжиться, если это - общий поток в приложении, как отправлено прежде.

Вот кавычка о возврате двух значений от функции:

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

я нашел, что он в запросе новых функций для Java позволяет , несколько возвращаемых значений

смотрят на датированный раздел "оценки": 06.05.2005 9:40:08

0
ответ дан Community 14 October 2019 в 14:45
поделиться

Я по всей вероятности пошел бы для чего-то как:


class SomeClass {
public int authenticate (Client client) {
//returns 0 if success otherwise one value per possible failure
}
public String getAuthenticationResultMessage (int authenticateResult) {}
//returns message associated to authenticateResult
}

С этим "дизайном", можно попросить сообщение только, когда аутентификация перестала работать (который я надеюсь, сценарий, который происходит 99,99% времени;))

Это может также иметь хорошую практику для делегирования разрешения сообщения к другому Классу. Но это зависит Ваших потребностей приложения (главным образом, этому нужен i18n?)

0
ответ дан Olivier 14 October 2019 в 14:45
поделиться

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

кроме того, если метод, который мог бы перестать работать, является "низким уровнем" - как прибытие из сервера приложений или слоя базы данных, я предпочел бы возвращать Перечисление со статусом возврата, и затем переводить это в строку на уровне GUI. Не раздавайте пользовательские строки на низком уровне, если Вы когда-либо собираетесь интернационализировать свой код, потому что тогда Ваш сервер приложений может только ответить на одном языке за один раз, вместо того, чтобы иметь различные клиенты, работающие на различных языках.

0
ответ дан Paul Tomblin 14 October 2019 в 14:45
поделиться

Просто, потому что неудачная аутентификация распространена, не означает, что это не исключительно.

, По-моему, ошибки аутентификации ребенок плаката вариант использования для контролируемых исключительных ситуаций. (Хорошо..., возможно, несуществование файла является каноническим вариантом использования, но ошибка аутентификации является близким № 2.)

1
ответ дан benjismith 14 October 2019 в 14:45
поделиться

Я лично думаю, создавая новый класс под названием AuthenticationStatus с булевской переменной, и Строка является большей частью Java как путь. И в то время как это походит на излишество (которым это может быть), это кажется инструментом для очистки мне и легче понять.

1
ответ дан Jacob Schoen 14 October 2019 в 14:45
поделиться

Вы могли возвратить Набор сообщений об ошибках, пустое указание, что не было никаких проблем. Это - улучшение Вашего третьего предложения.

1
ответ дан sblundy 14 October 2019 в 14:45
поделиться

Еще некоторые опции:

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

простой пример кортежа, фактическая реализация, возможно, нуждается в больше:

class Tuple<L, R> {

    public final L left;
    public final R right;

    public Tuple( L left, R right) {
        this.left = left;
        this.right = right;
    }
}
3
ответ дан Bas Leijdekkers 14 October 2019 в 14:45
поделиться

Постарайтесь не возвращать "значение сигнальной метки", особенно пустой. Вы закончите с кодовой базой, где методы не могут быть поняты под вызывающей стороной, не читая реализацию. В случае пустого указателя вызывающие стороны могут закончить с NullPointerExceptions, если они забывают (или не знайте), что Ваш метод может возвратить пустой указатель.

предложение кортежа от Bas Leijdekkers является хорошим, которое я использую все время, если я хочу возвратить больше чем одно значение из метода. Тот, который мы используем, P2<A, B> от библиотека Functional Java . Этот вид типа является совместным объединением двух других типов (это содержит одно значение каждого типа).

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

  1. Вы можете иметь Option<T> абстрактный класс с двумя подклассами Some<T> и None<T>. Это немного похоже на безопасную с точки зрения типов альтернативу пустому указателю и хороший способ реализовать частичные функции (функции, возвращаемое значение которых не определяется для некоторых аргументов). библиотека Functional Java имеет полнофункциональное Option класс, который реализует Iterable<T>, таким образом, можно сделать что-то вроде этого:

    public Option<String> authenticate(String arg) {
       if (success(arg))
          return Option.some("Just an example");
       else
          return Option.none();
    }
    
    ...
    
    for(String s : authenticate(secret)) {
       privilegedMethod();
    }
    
  2. , С другой стороны, можно использовать дизъюнктное объединение двух типов, как Either<L, R> класс. Это содержит одно значение, которое имеет любой тип L или R. Эти реализации класса Iterable<T> и для [1 112] и для R, таким образом, можно сделать что-то вроде этого:

    public Either<Fail, String> authenticate(String arg) {
       if (success(arg))
          return Either.right("Just an example");
       else
          return Either.left(Fail.authenticationFailure());
    }
    
    ...
    
    Either<Fail, String> auth = authenticate(secret);
    for(String s : auth.rightProjection()) {
       privilegedMethod();
    }
    for(Fail f : auth.leftProjection()) {
       System.out.println("FAIL");
    }
    

Все эти классы, P2, Option, и Either полезны в большом разнообразии ситуаций.

8
ответ дан Apocalisp 14 October 2019 в 14:45
поделиться

Вы могли использовать исключения....

try {
    AuthenticateMethod();
} catch (AuthenticateError ae) {         
    // Display ae.getMessage() to user..
    System.out.println(ae.getMessage());
    //ae.printStackTrace();    
}

и затем если ошибка происходит в Вашем AuthenticateMethod, Вы отправляете, новый AuthenticateError (расширяет Исключение)

13
ответ дан adam 14 October 2019 в 14:45
поделиться

Действительно ли это - единственный метод, где у Вас есть такое требование? В противном случае просто генерируйте общий класс Ответа с флагом isSuccessful и строкой сообщения и использованием это везде.

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

0
ответ дан Michael Borgwardt 14 October 2019 в 14:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: