1. 程式人生 > 實用技巧 >[Javascript] Joi for validation

[Javascript] Joi for validation

程序與執行緒

有一定基礎的小夥伴們肯定都知道程序和執行緒。

程序是什麼呢?

直白地講,程序就是應用程式的啟動例項。比如我們執行一個遊戲,開啟一個軟體,就是開啟了一個程序。

程序擁有程式碼和開啟的檔案資源、資料資源、獨立的記憶體空間。

執行緒又是什麼呢?

執行緒從屬於程序,是程式的實際執行者。一個程序至少包含一個主執行緒,也可以有更多的子執行緒。

執行緒擁有自己的棧空間。

有人給出了很好的歸納:

對作業系統來說,執行緒是最小的執行單元程序是最小的資源管理單元

無論程序還是執行緒,都是由作業系統所管理的。

協程

執行緒之間是如何進行協作的呢?

最經典的例子就是生產者/消費者模式

若干個生產者執行緒向佇列中寫入資料,若干個消費者執行緒從佇列中消費資料。

我們可以舉個簡單的例子:

public class ProducerConsumerTest {
 
    public static void main(String args[]) {
        final Queue<Integer> sharedQueue = new Queue();
        Thread producer = new Producer(sharedQueue);
        Thread consumer = new Consumer(sharedQueue);
        producer.start();
        consumer.start();
    }
}


class Producer extends Thread { private static final int MAX_QUEUE_SIZE = 5; private final Queue sharedQueue; public Producer(Queue sharedQueue) { super(); this.sharedQueue = sharedQueue; } @Override public void run() { for (int i = 0; i < 100; i++) {
synchronized (sharedQueue) { while (sharedQueue.size() >= MAX_QUEUE_SIZE) { System.out.println("佇列滿了,等待消費"); try { sharedQueue.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } sharedQueue.add(i); System.out.println("進行生產 : " + i); sharedQueue.notify(); } } } } class Consumer extends Thread { private final Queue sharedQueue; public Consumer(Queue sharedQueue) { super(); this.sharedQueue = sharedQueue; } @Override public void run() { while (true) { synchronized (sharedQueue) { while (sharedQueue.size() == 0) { try { System.out.println("佇列空了,等待生產"); sharedQueue.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int number = sharedQueue.poll(); System.out.println("進行消費 : " + number); sharedQueue.notify(); } } } }

1.定義了一個生產者類,一個消費者類。

2.生產者類迴圈100次,向同步(阻塞)隊列當中插入資料。

3.消費者迴圈監聽同步佇列,當佇列有資料時拉取資料。

4.如果佇列滿了(達到5個元素),生產者阻塞。

5.如果佇列空了,消費者阻塞。

上面的程式碼正確地實現了生產者/消費者模式,但是卻並不是一個高效能的實現。為什麼效能不高呢?原因如下:

1.涉及到同步鎖。

2.涉及到執行緒阻塞狀態和可執行狀態之間的切換。

3.涉及到執行緒上下文的切換。

以上涉及到的任何一點,都是非常耗費效能的操作。

所以這裡就會用到協程的概念

協程,英文Coroutines,是一種比執行緒更加輕量級的存在。正如一個程序可以擁有多個執行緒一樣,一個執行緒也可以擁有多個協程。

最重要的是,協程不是被作業系統核心所管理,而完全是由程式所控制(也就是在使用者態執行)。

這樣帶來的好處就是效能得到了很大的提升,不會像執行緒切換那樣消耗資源

既然協程這麼好,它到底是怎麼來使用的呢?

def consumer():
    while True:
        number = yield
        print('開始消費',number)

consumer = consumer()
next(consumer)
for num in range(100):
    print('開始生產',num)
    consumer.send(num)

這段程式碼十分簡單,即使沒用過python的小夥伴應該也能基本看懂。

程式碼中建立了一個叫做consumer的協程,並且在主執行緒中生產資料,協程中消費資料。

其中yield是python當中的語法。當協程執行到yield關鍵字時,會暫停在那一行,等到主執行緒呼叫send方法傳送了資料,協程才會接到資料繼續執行。

但是,yield讓協程暫停,和執行緒的阻塞是有本質區別的。協程的暫停完全由程式控制,執行緒的阻塞狀態是由作業系統核心來進行切換。

因此,協程的開銷遠遠小於執行緒的開銷。