[討論] 想設計出一種一對多的Lock (inter-process)
Hi
我想要做一種client-server架構的Lock, 可以讓許多個client去wait
而server可以決定什麼時候該Lock (所有client在做Lock的時候會卡住)
什麼時候該Unlock (所有client在做Lock的時候會do nothing)
我的需求是這樣子的:
我有一個ringbuffer實作在shared memory裡
ringbuffer的每一塊資料都有一個編號, 這個編號只會逐漸增加
這塊sharememory的最前面會有一個表格, 記錄每個編號的data在ringbuffer的哪一個offset
新的資料會被插進來, 太久遠的資料會被丟棄
比如說目前的ringbuffer裡面資料是這樣分布的 1, 2, 3, 4, 5
這時候會有一個新的資料加進來, 他的編號會是6
而ringbuffer已經滿了, 所以1號會被丟棄
所以ringbuffer資料分佈會變成這樣 2, 3, 4, 5, 6
(先不管資料應該怎麼排列順序還有critical section的設計, 因為這不在討論之中)
回到我的問題:
當我的client已經把6號讀走了, 想要繼續讀7號(但是7號還沒被加進來)
client就必須等待server把7號加進來
目前我的方法是client在for迴圈裡面做usleep(1000), 然後一直問7號來了沒
想也知道這樣很浪費系統資源
我打算這樣做:
設計一個semaphore, 平常的值為0
如果有一個client打算抓取還沒產生的data的時候(7號)
因為從表格中判斷出ringbuffer並不存在7號(也不知道甚麼時候會有)
所以client對這個semaphore減1 (然後程式卡住)
當server已經準備好7號data的時候, 就對這個semaphore加100(也許更多)
讓所有卡住的client都會瞬間解除blocking
當blocking解除之後server再把semaphore的值設為0
我的Linux還算很嫩, 目前想到的也就這招, 不知道大家還有什麼更好的辦法?
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.32.91.30
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1441092306.A.101.html
→
09/01 16:13, , 1F
09/01 16:13, 1F
→
09/01 16:14, , 2F
09/01 16:14, 2F
→
09/01 16:32, , 3F
09/01 16:32, 3F
→
09/01 16:32, , 4F
09/01 16:32, 4F
→
09/01 16:34, , 5F
09/01 16:34, 5F
→
09/01 16:36, , 6F
09/01 16:36, 6F
→
09/01 18:54, , 7F
09/01 18:54, 7F
推
09/01 19:53, , 8F
09/01 19:53, 8F
推
09/01 23:35, , 9F
09/01 23:35, 9F
→
09/02 19:16, , 10F
09/02 19:16, 10F
→
09/02 19:17, , 11F
09/02 19:17, 11F
→
09/02 19:18, , 12F
09/02 19:18, 12F
推
09/02 19:30, , 13F
09/02 19:30, 13F
→
09/03 03:30, , 14F
09/03 03:30, 14F
我利用semaphore做成這樣:
semaphore剛建立出來的時候, 把semaphore的值設為0 (這樣任何想要-1的client都會被卡住)
在server端想要送一個signal給所有卡住的client時, 就這樣做
semctl(id, 0, SETVAL, 100); // 這會讓所有卡住的client unlock
semctl(id, 0, SETVAL, 0); // 恢復為常態, 讓下次想要lock的client會立刻卡住
在client端就只是單純的-1而已
struct sembuf sb;
sb.sem_num = 0;
sb.sem_op = -1;
sb.sem_flg = 0;
semop(id, &sb, 1);
※ 編輯: jaw109 (114.32.91.30), 09/03/2015 12:41:06
→
09/03 16:28, , 15F
09/03 16:28, 15F
感謝yvb的指點, 我改成這樣了
semaphore剛建立出來的時候, 把semaphore的值設為1 (這樣任何想要做sem_op = 0的client都會被卡住)
在server端想要送一個signal給所有卡住的client時, 就這樣做
semctl(id, 0, SETVAL, 0); // 這會讓所有卡住的client unlock
semctl(id, 0, SETVAL, 1); // 恢復為常態, 讓下次想要做sem_op=0的client會立刻卡住
在client端就做sem_op=0
struct sembuf sb;
sb.sem_num = 0;
sb.sem_op = 0;
sb.sem_flg = 0;
semop(id, &sb, 1);
[A
※ 編輯: jaw109 (114.32.91.30), 09/03/2015 18:11:55
→
09/06 22:01, , 16F
09/06 22:01, 16F
→
09/06 22:02, , 17F
09/06 22:02, 17F
→
09/07 14:51, , 18F
09/07 14:51, 18F
→
09/07 14:51, , 19F
09/07 14:51, 19F
→
09/08 23:25, , 20F
09/08 23:25, 20F
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章