Location>code7788 >text

The synchronous blocking asynchronous non-blocking that has been confusing PHP programmers has finally been figured out!

Popularity:336 ℃/2024-08-05 10:02:16

Hi everyone, I'm Codemaster Pioneer.

I'm often surprised to hear my friends who write Java and Go talk about asynchronous, non-blocking, threaded, and concurrent programs that increase system performance to millions or tens of millions of concurrencies, and I'm really envious of them. For me, who has been writing PHP for years, when I first heard these words, my head was in a state of confusion, and when I looked back at the synchronous blocking PHP code in my hand, I thought to myself, "What in the world are "asynchronous, non-blocking, threading, and co-programming", and what are they, and are they so powerful? In fact, there are threads and concurrent threads in PHP, but they are hardly used in everyday programming because PHP-FPM does not support threads and concurrent threads in multiprocess mode, and most programmers who use PHP cannot live without PHP-FPM. This also leads to PHP programmers have no contact with those concepts, let alone understand them. Therefore, in order for the majority of fellow PHP programmers to be able to talk to Java and Go programmers, we have made an in-depth analysis of the concepts of synchronous, blocking, asynchronous, and non-blocking in an effort to straighten out the PHP programmer's backbone.

As is customary, the dish of the eight-legged essay will be served first:

  • Synchronized Blocking: When an operation is called, the caller is blocked until this operation completes and returns the result. During this time, the caller cannot perform other tasks.
  • Asynchronous blocking: when an operation is called, the caller is not blocked and can continue with other tasks. However, it still needs to wait for the called operation to complete and process its result when it does. This waiting process may be blocking.
  • Synchronized non-blocking: After the caller initiates an operation, it is not blocked and can continue with other tasks. Although the caller can gain control immediately, it still has to wait for the operation to complete before it can process the result. While waiting, the caller can actively poll or keep trying to get the result of the operation to avoid long blocking times.
  • Asynchronous non-blocking: after the caller initiates an operation, it is not blocked and can continue to perform other tasks. Also, the caller does not need to wait for the operation to complete to process the result. Instead, the caller can register a callback function or use an event-driven mechanism that is automatically triggered when the operation completes to process the result.

The basics of solid friends to see this eight-legged text is enough to solve the puzzle, but to see the eight-legged text is, after all, a handful of handsome handsome people, you say the gas is not gas people set value and talent in one, don't look at that is to say that you look at the official "haha". Back to the topic, that do not understand the eight-legged text how to get? Don't worry, and listen to me combined with examples of life to tell.

You go to work every day hurriedly passed the breakfast store, today extra people, you get close to look at the original is to come to a high stature Chuchu beautiful waitress, the results you can not resist the excitement in your heart, today high and low have to buy two steamed buns plus a cup of soybean milk, due to buy too many people, steamed steamed buns have long been sold out, at this time you can only wait for is steaming, during the period of time you can't do anything but eye hooks dry waiting, then at this time You are synchronized with the blockage.

As more and more people come to buy breakfast, from the time of work is getting closer and closer, you began a commotion, every few minutes to ask the beautiful waiter steamed buns? At this time you no longer dry and so on, but began to brush the jitterbug to see the work group, because you have paid so still have to wait for the steamed buns, due to the beauty of the waiter is too busy to take the initiative to tell you, you need to ask yourself constantly, then at this time you are synchronized non-blocking.

After the peak of the people become less, the field of vision is broader, you see the beautiful waiter more clear, the results you began to eye hook dry waiting, jitterbug also do not brush the news of the work group also disregarded. As the beautiful waiter is not busy, began to take the initiative to call that wearing a plaid shirt back shoulder bag handsome, steamed buns steamed, at this time you shook off the bangs on the head, took over the beautiful waiter in the hands of the steamed buns will smile, by the way, but also added the other party's WeChat, then at this time you are asynchronous blocking.

The next day you in order to see the face again, and came to the breakfast store, always stingy, you ordered two meat buns. At this time, the beautiful waitress to meet the smiling face to inform you of meat packets still need to wait patiently Oh, steamed well will notify you by WeChat. In the hot summer you walk on the road in too much of a hurry, at this time you are thirsty, go next door to the kiosk to buy a bottle of 82 years of Coke, but also sat and blew the air conditioning. With a Dingdong of WeChat, you get up to go to the breakfast store, took the beautiful waiter in the hands of the meat bag, then at this time you are asynchronous non-blocking.

With the beautiful waitress feeding, you work full of energy, but also should be "synchronous, blocking, asynchronous, non-blocking" the concept of understanding it. In fact, here synchronous asynchronous and blocking non-blocking, easy to get confused as you look at the beautiful waiter easy to lose soul, in this example synchronous asynchronous need to focus on "beautiful waiter will take the initiative to notify you", the initiative to notify you then for you is asynchronous, you need to ask then for you is synchronous. Blocking non-blocking need to focus on the point is "whether you are eye hook dry waiting", if you can only dry waiting that is blocking, if you can also do something else such as brush Jieyin, buy 82 years of Coke, then it is non-blocking.

Beauty also look at the reason also understand, some of our friends to produce new questions, that in the program how to reflect, how to use "synchronous, blocking, asynchronous, non-blocking"? Then we started on the code, after all, look at the beautiful waiter's purpose is also to be able to deepen the relationship, it is the same as the practice of hands-on, you taste is not this reason.

Open the whole thing!

Let's start withsynchronous blockingIn the example above, the socket_create, socket_bind, and socket_listen functions create bindings and listen on port 8080, and then block on the socket_accept function until a client connection is received. Traditionally, PHP-FPM is a synchronous blocking model, but with the PHP-FPM multiprocessing model, the socket_accept function will block until a client connection is received.$client The process is then handed over to the child process for subsequent processing, in this example only the single process mode is exemplified.

<?php

// Synchronized blocking mode

// Create a listening socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// Bind to port 8080
socket_bind($socket, '0.0.0.0', 8080); // Create a listening socket.

// Start listening
socket_listen($socket); // Start listening.

socket_listen($socket); while(true){
    // It will block here, waiting for the client to connect.
    // Combined with the example just given, this means that you're waiting for the client to connect, but you can't do anything about it.
    $client = socket_accept($socket); if($client){
    if($client){
        echo "Guest is here" . PHP_EOL; }
    }
}

Let's go over it again.synchronous non-blockingexample, which also listens on port 8080, the difference being that the socket$socket is set to non-blocking mode. In this case, the socket_accept function will not keep blocking, it will continue to execute, and if no other logic is written, it will be empty. This mode in the actual programming will not be used, the system will be drained, it is worth noting that whoever writes such code will be pulled out of the penalty box.

<?php

// Synchronized non-blocking mode

// Create a listening socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// Bind to port 8080
socket_bind($socket, '0.0.0.0', 8080); // Create a listening socket.

// Start listening
socket_listen($socket); // Start listening.

// Set this to non-blocking
socket_set_nonblock($socket); // Set this to non-blocking.

socket_set_nonblock($socket); while(true){
    // Not blocking here
    $client = socket_accept($socket); if($client){ // do not block here.
    if($client){
        echo "Guest is here" . PHP_EOL.
    }

    // The execution will continue down the line
    // In conjunction with the example just given, you can swipe through Shakeology, check your workgroup messages, etc. here
    // ...

    // If you didn't write any logic above, it's a good idea to sleep on these.
    // Otherwise the CPU will be drained, i.e. don't keep staring at the pretty waitress.
    // Take a break.
    sleep(5); }
}

Keep looking.asynchronous blockingIt's a good thing we have Swoole, otherwise we wouldn't be able to find examples of this pattern, thanks to Swoole's contribution to PHP programmers for giving us a hard time. We've constructed an HTTP service that listens on port 9501 and set up an asynchronous callback function for the Request, but if we use PHP-native functions like sleep, PDO, etc. inside the callback function, it blocks the entire process and prevents us from processing other Requset requests. The performance of the program in this case is directly equivalent to synchronous blocking, so asynchronous blocking mode is not commonly used in actual programming practice, and it is better to use synchronous blocking mode. As a reminder, in the new version of Swoole, it is now possible to support PHP's native function concatenation by means of HOOK, which is also a good thing.

<?php

// Asynchronous blocking mode

// Create a Swoole asynchronous HTTP server
$http = new Swoole\Http\Server('127.0.0.1', 9501);

// Set up the asynchronous callback function
$http->on('request', function ($request, $response) {
    // Blocks the entire process; using PHP's native PDO, Redis, etc. will block the current process.
    // Combine this with the example above, and you're just waiting, there's nothing you can do here.
    sleep(5);

    $response->end("OK").
}); $response->end("OK");

// Start the server
$http->start();

Let's take a final look.asynchronous non-blockingThe only difference between the above example and the one above is the use of a concatenated class in the Request callback function, which does not block the entire process and frees up CPU control to handle other requests. Of course, in the new version of Swoole, you don't necessarily need to use a co-processor class, you can use a native function that also doesn't block the process, which greatly reduces the mental burden of programming for PHP programmers.

<?php

// Asynchronous non-blocking mode

// Create an asynchronous HTTP server for Swoole
$http = new Swoole\Http\Server('127.0.0.1', 9501);

// Set up the asynchronous callback function
$http->on('request', function ($request, $response) {
    // Doesn't block the entire process, you can also use other co-processing clients like this one
    // swoole\Coroutine\MySQL
    // swoole\Coroutine\Redis
    // In conjunction with the example just given, here you can go to Shake Shack and buy an '82 Coke.
    // That means you're free to handle other requests instead of waiting here.
    // After the 5 seconds have passed, you can come back and continue down the line, and after you've picked up your meatloaf, you can go to work, even though you've got a lot on your mind.
    Co::sleep(5);

    $response->end("OK").
});

// Start the server
$http->start();

Although you still can't forget the face of the pretty waitress at the breakfast parlor, your empty pockets are urging you to get to work. See here you not only appreciate the beauty of the face, but also "synchronous, blocking, asynchronous, non-blocking" also understand, simply the best of both worlds, understand the concepts of the future of Go language learning is also very beneficial. But we all know the truth, see understand does not equal to really understand, many people will look at a do a waste, so it is best to practice their own hands, in the knowledge of the line, in the line of knowledge, to achieve the unity of knowledge and action, like looking at the beautiful waiter is not the purpose but want to go deeper into a step of communication, stop there haha. The vast majority of high-performance programs on the market are asynchronous non-blocking mode, such as Nginx, Redis, etc., if you want to write a high-performance program is best to give priority to this mode, because learning is the fastest way to learn. The content of this sharing to this end, I hope to help you.

Thanks for reading, personal opinion is for reference only, welcome to express different views in the comment section.


Welcome to follow, share, like, favorite, in the watch, I'm the author of WeChat public number "code farmer forefather".