看板 C_and_CPP 關於我們 聯絡資訊
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
Hazukashiine: 也許可以考慮改用 mutex 來實踐 09/01 16:13
Hazukashiine: 記得要處理好 deadlock 的問題就好了 09/01 16:14
jaw109: @Hazukashiine 您是指POSIX mutex? 這可以在interprocess 09/01 16:32
jaw109: 使用嗎? 09/01 16:32
Hazukashiine: 你是說 IPC 嗎?我不確定,不過你可以先自己找一下 09/01 16:34
Hazukashiine: http://goo.gl/gGKW2P 09/01 16:36
shadow0326: google一下pthread wait broadcast 09/01 18:54
yvb: 看起來 semaphore 就可以辦到了啊. 09/01 19:53
ah7675: reader writer lock? 09/01 23:35
Caesar08: 如果你一次只會加1個,我認為condition_variable就夠用 09/02 19:16
Caesar08: 不過你說一次會加多個,那應該要用semaphore 09/02 19:17
Caesar08: readers writers的問題應該符合你的需求 09/02 19:18
clementchen: 你想做的可能是disruptor pattern..請自查:) 09/02 19:30
firejox: monitor ? 09/03 03:30
我利用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
yvb: 請試著考慮 sem_op = 0 可以怎麼使用. 09/03 16:28
感謝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
adrianshum: Reader Writer Lock 就可以了。Client acquire 09/06 22:01
adrianshum: read lock, server acquire write lock 09/06 22:02
jaw109: 我自己其實有實作read-write lock, 但改成文中的需求並不 09/07 14:51
jaw109: 適合 09/07 14:51
ah7675: condition variable + wait_queue 09/08 23:25