Programming

메소드를 스레드로부터 안전하게 만드는 것은 무엇입니까?

procodes 2020. 6. 18. 22:21
반응형

메소드를 스레드로부터 안전하게 만드는 것은 무엇입니까? 규칙은 무엇입니까?


메소드를 스레드로부터 안전하게 만드는 것에 대한 전반적인 규칙 / 지침이 있습니까? 일회성 상황이 백만 건일 수 있지만 일반적으로 어떻습니까? 이것이 간단합니까?

  1. 메소드가 로컬 변수에만 액세스하는 경우 스레드 안전합니다.

그게 다야? 정적 메소드에도 적용됩니까?

@Cybis가 제공 한 한 가지 대답은 다음과 같습니다.

각 스레드는 자체 스택을 가져 오기 때문에 스레드간에 로컬 변수를 공유 할 수 없습니다.

정적 메소드도 마찬가지입니까?

메소드에 참조 객체가 전달되면 스레드 안전성이 손상됩니까? 나는 약간의 연구를 해왔고, 어떤 경우에 대해서는 많은 것이 있지만, 몇 가지 규칙을 사용하여 방법이 스레드 안전하다는 것을 보장하기 위해 따라야 할 지침을 정의 할 수 있기를 바랐습니다.

따라서 궁극적 인 질문은 "스레드 안전 방법을 정의하는 짧은 규칙 목록이 있습니까? 그렇다면 그렇다면 무엇입니까?"입니다.

편집
여기에는 많은 좋은 점이 있습니다. 이 질문에 대한 진정한 대답은 "스레드 안전을 보장하는 간단한 규칙은 없습니다"라고 생각합니다. 멋있는. 좋아. 그러나 일반적으로 나는 받아 들인 대답이 짧고 좋은 요약을 제공한다고 생각합니다. 항상 예외가 있습니다. 그러면 그렇게 해. 나는 그걸로 살 수 있습니다.


메소드 (인스턴스 또는 정적)가 해당 메소드 내에서 범위가 지정된 변수 만 참조하는 경우 각 스레드에는 자체 스택이 있으므로 스레드 안전합니다.

이 경우 여러 스레드가 ThreadSafeMethod문제없이 동시에 호출 될 수 있습니다.

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number; // each thread will have its own variable for number.
        number = parameter1.Length;
        return number;
    }
}

메소드가 로컬 범위 변수 만 참조하는 다른 클래스 메소드를 호출하는 경우에도 마찬가지입니다.

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number;
        number = this.GetLength(parameter1);
        return number;
    }

    private int GetLength(string value)
    {
        int length = value.Length;
        return length;
    }
}

메소드가 (객체 상태) 속성 또는 필드 (인스턴스 또는 정적)에 액세스하는 경우 다른 스레드에서 값을 수정하지 않도록 잠금을 사용해야합니다.

public class Thing
{
    private string someValue; // all threads will read and write to this same field value

    public int NonThreadSafeMethod(string parameter1)
    {
        this.someValue = parameter1;

        int number;

        // Since access to someValue is not synchronised by the class, a separate thread
        // could have changed its value between this thread setting its value at the start 
        // of the method and this line reading its value.
        number = this.someValue.Length;
        return number;
    }
}

구조체 나 불변이 아닌 메서드에 전달 된 모든 매개 변수는 메서드 범위 밖의 다른 스레드에 의해 변경 될 수 있습니다.

적절한 동시성을 보장하려면 잠금을 사용해야합니다.

자세한 정보는 잠금 문 C # 참조ReadWriterLockSlim을 참조 하십시오 .

lock 은 대부분 한 번에 하나씩 기능을 제공하는 데 유용하며
ReadWriterLockSlim여러 독자와 단일 작성자가 필요한 경우 유용합니다.


메소드가 로컬 변수에만 액세스하는 경우 스레드 안전합니다. 그게 다야?

Absolultely not. You can write a program with only a single local variable accessed from a single thread that is nevertheless not threadsafe:

https://stackoverflow.com/a/8883117/88656

Does that apply for static methods as well?

Absolutely not.

One answer, provided by @Cybis, was: "Local variables cannot be shared among threads because each thread gets its own stack."

Absolutely not. The distinguishing characteristic of a local variable is that it is only visible from within the local scope, not that it is allocated on the temporary pool. It is perfectly legal and possible to access the same local variable from two different threads. You can do so by using anonymous methods, lambdas, iterator blocks or async methods.

Is that the case for static methods as well?

Absolutely not.

If a method is passed a reference object, does that break thread safety?

Maybe.

I've done some research, and there is a lot out there about certain cases, but I was hoping to be able to define, by using just a few rules, guidelines to follow to make sure a method is thread safe.

You are going to have to learn to live with disappointment. This is a very difficult subject.

So, I guess my ultimate question is: "Is there a short list of rules that define a thread-safe method?

Nope. As you saw from my example earlier an empty method can be non-thread-safe. You might as well ask "is there a short list of rules that ensures a method is correct". No, there is not. Thread safety is nothing more than an extremely complicated kind of correctness.

Moreover, the fact that you are asking the question indicates your fundamental misunderstanding about thread safety. Thread safety is a global, not a local property of a program. The reason why it is so hard to get right is because you must have a complete knowledge of the threading behaviour of the entire program in order to ensure its safety.

Again, look at my example: every method is trivial. It is the way that the methods interact with each other at a "global" level that makes the program deadlock. You can't look at every method and check it off as "safe" and then expect that the whole program is safe, any more than you can conclude that because your house is made of 100% non-hollow bricks that the house is also non-hollow. The hollowness of a house is a global property of the whole thing, not an aggregate of the properties of its parts.


There is no hard and fast rule.

Here are some rules to make code thread safe in .NET and why these are not good rules:

  1. Function and all functions it calls must be pure (no side effects) and use local variables. Although this will make your code thread-safe, there is also very little amount of interesting things you can do with this restriction in .NET.
  2. Every function that operates on a common object must lock on a common thing. All locks must be done in same order. This will make the code thread safe, but it will be incredibly slow, and you might as well not use multiple threads.
  3. ...

There is no rule that makes the code thread safe, the only thing you can do is make sure that your code will work no matter how many times is it being actively executed, each thread can be interrupted at any point, with each thread being in its own state/location, and this for each function (static or otherwise) that is accessing common objects.


It must be synchronized, using an object lock, stateless, or immutable.

link: http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

참고URL : https://stackoverflow.com/questions/9848067/what-makes-a-method-thread-safe-what-are-the-rules

반응형