1.什么是單進程 ,什么是多進程
當一個程序開始運行時,它就是一個進程,進程包括運行中的程序和程序所使用到的內存和系統資源。而一個進程又是由單個或多個線程所組成的。
1.1 ?像apache ?nginx 這類 服務器中間件就是多進程的軟件 , cpu會使用多個進程完成用戶的操作請求。
>> ps aux | grep httpd
apache 18352 0.0 4.4 1833072 84584 ? Sl 03:27 0:00 /usr/local/apache/bin/httpd -k start
apache 18353 0.0 4.3 1837212 82128 ? Sl 03:27 0:00 /usr/local/apache/bin/httpd -k start
apache 22655 0.0 1.5 777480 29676 ? Ss Aug20 1:31 /usr/local/apache/bin/httpd -k start
apache 23640 0.0 6.2 1839004 117148 ? Sl 14:07 0:00 /usr/local/apache/bin/httpd -k start
apache 24321 0.1 7.1 1838872 135012 ? Sl 15:39 0:00 /usr/local/apache/bin/httpd -k start
1.2 像 redis ,lua這類軟件就是單進程的 ,無論再多的操作請求 ,cpu只會生成一個進程來處理事情。
>> ps aux | grep redis
root 22931 0.1 0.0 140916 1472 ? Ssl Aug20 27:40 ./redis-server *:88888
2. 單線程 ?和 多線程怎么理解
線程是程序中的一個執行流,每個線程都有自己的專有寄存器(棧指針、程序計數器等),但代碼區是共享的,即不同的線程可以執行同樣的函數。
2.1 什么是多線程?
多線程是指程序中包含多個執行流,即在一個程序中可以同時運行多個不同的線程來執行不同的任務,也就是說允許單個程序創建多個并行執行的線程來完成各自的任務。
2.2 多線程的好處和壞處
好處:可以提高CPU的利用率。在多線程程序中,一個線程必須等待的時候,CPU可以運行其它的線程而不是等待,這樣就大大提高了程序的效率。
壞處:當然多線程也有壞處,因為線程也是程序,所以線程需要占用內存,線程越多占用內存也越多;多線程需要協調和管理,所以需要CPU時間跟蹤線程;線程之間對共享資源的訪問會相互影響,必須解決競用共享資源的問題;線程太多會導致控制太復雜,最終可能造成很多Bug;
2.3 單線程 和 多線程的區別
生活舉例
你早上上班,正要打卡的時候,手機響了。。你如果先接了電話,等接完了,再打卡,就是單線程。
如果你一手接電話,一手打卡。就是多線程。
2件事的結果是一樣的。。你接了電話且打了卡。
3. lua+redis為什么能解決高并發超賣 ,應用場景
$REDIS_REMOTE_HT_KEY = "product_%s"; //共享信息key$REDIS_REMOTE_TOTAL_COUNT = "total_count"; //商品總庫存$REDIS_REMOTE_USE_COUNT = "used_count"; //已售庫存$script = <<<eoflocal key = KEYS[1]local field1 = KEYS[2]local field2 = KEYS[3]local field1_val = redis.call('hget', key, field1)local field1_val = tonumber(field1_val)local field2_val = redis.call('hget', key, field2)local field2_val = tonumber(field2_val)if(field1_val>field2_val) thenreturn redis.call('HINCRBY', key, field2,1)endreturn 0
eof;$objRedis = new \Redis();$objRedis->connect('127.0.0.1',6379);$objRedis->auth('1234');$r = $objRedis->eval($script,array($REDIS_REMOTE_HT_KEY,$REDIS_REMOTE_TOTAL_COUNT,$REDIS_REMOTE_USE_COUNT),3);if($r==0){echo '商品已經買完了哦...';...}
上面的是lua+redis防止超賣的 php 代碼片段 , 我們預先在服務器上設置了?商品總庫存?total_count 為 100
./ab -n 300 -c 300 'http://127.0.0.1/'
測試300個并發。可以看到最終?已售庫存?used_count ,剛好是100 ,并沒有出現超賣的現象
為什么lua+redis 能解決 這種超賣現象
1. 原子操作。Redis會將整個腳本作為一個整體執行,中間不會被其他請求插入。因此在腳本運行過程中無需擔心會出現競態條件,無需使用事務。
2. 復用。客戶端發送的腳本會永久存在redis中,這樣其他客戶端可以復用這一腳本,而不需要使用代碼完成相同的邏輯。
4. lua的一些語法基礎
4.1 hello world
print("Hello World!")
不用分號 .
4.2 注釋
--兩個減號是單行注釋:--[[多行注釋多行注釋--]]
4.3 變量
Lua 變量有三種類型:全局變量、局部變量、表中的域。
Lua 中的變量全是全局變量,那怕是語句塊或是函數里,除非用 local 顯式聲明為局部變量。
局部變量的作用域為從聲明位置開始到所在語句塊結束。
變量的默認值均為 nil。
a = 5 -- 全局變量
local b = 5 -- 局部變量function joke()c = 5 -- 全局變量local d = 6 -- 局部變量
endjoke()
print(c,d) --> 5 nil
這點和php不大一樣,變量C在 function里 ,就是局部的 。 第10行的?print(c,d) 是讀取不大的
4.4 循環
a=10
while( a < 20 )
doprint("a 的值為:", a)a = a+1
end
4.5 控制
要注意的是Lua中 0 為 true
--[ 定義變量 --]
a = 10;--[ 使用 if 語句 --]
if( a < 20 )
then--[ if 條件為 true 時打印以下信息 --]print("a 小于 20" );
end
print("a 的值為:", a);