Multithreaded programming infrastructure for LINUX environments

Source: Internet
Author: User
This paper introduces the infrastructure of parallel programming in multi-threaded environment. Mainly include:

    • Volatile

    • __thread

    • Memory Barrier

    • __sync_synchronize

    • Volatile

The compiler sometimes optimizes the performance by caching the values of some variables into registers, so if the compiler finds that the value of the variable is unchanged, the value will be read from the register, which avoids memory access.

But there are sometimes problems with this approach. What if the variable does (in a way that is difficult to detect) be modified? Wouldn't that be the wrong value to read? Yes. In multithreaded situations, the problem is even more pronounced: when a thread modifies a memory unit, other threads may read the variable from the register if it reads the old value, the value that is not updated, the value of the error, and the value that is not fresh.

How do you prevent such errors from being "optimized"? The method is to add a volatile modifier to the variable.

volatile int i=10;//with volatile modifier variable i......//something happenedint b = i;//Force reads the value of real-time I from memory

OK, after all, the volatile is not perfect, it also limits the optimization to some extent. Sometimes there is a need: I want you to immediately read the data in real time, you access the memory, do not optimize, otherwise, you should optimize or optimize your. Can you do that?

Without the volatile modifier, you can't get to the front. Added volatile, the latter aspect of the impossible to talk about, how to do? Racking

In fact, we can do this:

int i = 2; Variable i or no volatile modifier # access_once (x) (* (volatile typeof (X) *) & (x))

When you need to read the value of I in real time, call Access_once (i), otherwise I can be used directly.

This trick, I was from "is parallel programming hard?" "To the school.


Sounds all right? However, dangerous: volatile is often misused, and many people often do not know or ignore its two features: in C + + language, volatile does not guarantee atomicity; Using volatile should not have any memory barrier expectations.


1th better understand, for the 2nd, let's look at a very classic example:

volatile int is_ready = 0;char message[123];void thread_a{  while (Is_ready = = 0)  {  }  //use message;} void thread_b{  strcpy (message, "Everything seems OK");  Is_ready = 1;}

In thread B, although Is_ready has a volatile modifier, the volatile here does not provide any memory Barrier, so 12 rows and 13 rows may be executed in a disorderly order, Is_ready = 1 executed, and the message is not set correctly. Causes thread A to read to the wrong value.

This means that using volatile in multi-threading requires a lot of care and caution.

__thread

__thread is a built-in infrastructure for multithreaded programming in GCC. With __thread modified variables, each thread has a copy of the entity, independent of each other and not interfering with each other. As an example:

#include #include#includeusing namespace Std;__thread int i = 1;void* thread1 (void* arg); void* thread2 (void* arg); int main () {  pthread_t pthread1;  pthread_t pthread2;  Pthread_create (&pthread1, NULL, THREAD1, NULL);  Pthread_create (&pthread2, NULL, thread2, NULL);  Pthread_join (Pthread1, NULL);  Pthread_join (Pthread2, NULL);  return 0;} void* thread1 (void* Arg) {  coutiendl;//output 2    return NULL;} void* thread2 (void* arg) {  sleep (1);//waits for thread1  to finish updating coutiendl;//output 2 instead of 3  return NULL;}


It is important to note that:

1,__thread can modify global variables, static variables of functions, but cannot modify local variables of a function.

2, variables modified by __thread can only be initialized at compile time, and can only be initialized by constant expressions.

Memory Barrier

For optimization, modern compilers and CPUs may execute instructions in a disorderly sequence. For example:

int a = 1;int b = 2;a = b + 3;b = 10;


After the CPU is out of order, the order of execution of the 4th and 5th statements may change to first b=10 and then a=b+3

Some people may say, is that the result is wrong? B is 10,a for 13? But the correct result should be a of 5 ah.

Oh, here is the statement execution, the corresponding assembly instructions are not simple mov b,10 and mov b,a+3.

The resulting assembly code might be:

MOVL    B (%rip),%eax; The value of B is temporarily deposited in%eaxmovl    , B (%rip), B = 10addl    ,%eax,%eax plus 3MOVL    %eax, A (%rip);%eax That is, the value of B+3 is written to a, which is a = B + 3


It's not surprising that in order to optimize performance, it is sometimes possible to do so. But in multi-threaded parallel programming, sometimes there are problems in the chaos sequence.

One of the most typical examples is to protect the critical section with a lock. If the code of the critical section is pulled to the lock or after the lock is released, it will result in ambiguous results, often causing unhappiness.

There are, for example, arbitrary reading data and write data disorderly order, then originally read and write, and then read the first to write after reading the dirty data behind. Therefore, Memory barrier is used to prevent the execution of chaotic sequences. Specifically, Memory Barrier consists of three types:

1,acquire barrier. Acquire barrier after the instruction cannot and will not be pulled to the acquire barrier before execution.

2,release barrier. The instructions before the release barrier cannot and will not be pulled to the release barrier after execution.

3,full barrier. These two kinds of collections.

So, it is easy to know, lock, that is, lock corresponds to acquire barrier; release lock, that is unlock corresponds to release barrier. Oh, what about full barrier?

__sync_synchronize

__sync_synchronize is a full barrier.

The above is the Linux environment multithreaded programming infrastructure content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.