Интеррапт
Уже с Приветом
Posts: 17281 Joined: 07 Sep 2011 10:05
Location: Seattle, WA
Post
by Интеррапт » 12 Feb 2014 09:04
Ну раз пошла такая пьянка, то и мы парикмахера напишем:
Code: Select all
class Barber:
event = threading.Event()
def cut_hair(self, customer):
print "CUSTOMER {}: haircut (begin)".format(customer.id)
self.event.clear()
time.sleep(AVG_HAIRCUT_TIME)
print "CUSTOMER {}: haircut (end)".format(customer.id)
def sleep(self):
self.event.wait()
def wake_up(self):
self.event.set()
class Customer:
id = None
def __init__(self, id):
self.id = id
class BarberShop:
barber = None
pending_customers = []
def __init__(self):
BarberShop.lock = threading.Lock()
self.barber = Barber()
th = threading.Thread(target=self.do_work)
th.start()
def do_work(self):
while True:
BarberShop.lock.acquire()
if len(self.pending_customers) > 0:
customer = self.pending_customers.pop(0)
BarberShop.lock.release()
self.barber.cut_hair(customer)
else:
BarberShop.lock.release()
print "BARBER: No customers, time to nap..."
self.barber.sleep()
print 'BARBER: New customer has arrived, wake up!'
def enter(self, customer):
BarberShop.lock.acquire()
print "CUSTOMER {}: entered a shop".format(customer.id)
if len(self.pending_customers) == NUMBER_OF_SEATS:
BarberShop.lock.release()
print "CUSTOMER {}: Wow, barber shop is full, I'm out of here!".format(customer.id)
else:
print "CUSTOMER {}: No worries, I'll wait".format(customer.id)
self.pending_customers.append(customer)
BarberShop.lock.release()
self.barber.wake_up()
Интеррапт
crypto5
Уже с Приветом
Posts: 4637 Joined: 24 Oct 2009 01:38
Location: Chicago ;-) -> SFBA!
Post
by crypto5 » 12 Feb 2014 09:09
А вот если окажется что барберов 10, то мне нужно будет одну цифру поменять, а ты будешь плодить баги и дедлоки
In vino Veritas!
crypto5
Интеррапт
Уже с Приветом
Posts: 17281 Joined: 07 Sep 2011 10:05
Location: Seattle, WA
Post
by Интеррапт » 12 Feb 2014 09:12
crypto5 wrote: А вот если окажется что барберов 10, то мне нужно будет одну цифру поменять, а ты будешь плодить баги и дедлоки
Просто тебе стыдно стало, что ты кучу потоков развел на ровном месте.
Интеррапт
crypto5
Уже с Приветом
Posts: 4637 Joined: 24 Oct 2009 01:38
Location: Chicago ;-) -> SFBA!
Post
by crypto5 » 12 Feb 2014 09:14
Интеррапт wrote: crypto5 wrote: А вот если окажется что барберов 10, то мне нужно будет одну цифру поменять, а ты будешь плодить баги и дедлоки
Просто тебе стыдно стало, что ты кучу потоков развел на ровном месте. Джавис, что тут скажешь.
Столько же сколько и ты развел
In vino Veritas!
crypto5
Интеррапт
Уже с Приветом
Posts: 17281 Joined: 07 Sep 2011 10:05
Location: Seattle, WA
Post
by Интеррапт » 12 Feb 2014 09:16
crypto5 wrote: Интеррапт wrote: crypto5 wrote: А вот если окажется что барберов 10, то мне нужно будет одну цифру поменять, а ты будешь плодить баги и дедлоки
Просто тебе стыдно стало, что ты кучу потоков развел на ровном месте. Джавис, что тут скажешь.
Столько же сколько и ты развел
Да я даже не про этот конкретный случай, а про F/J Pool c I/O операциями
Интеррапт
crypto5
Уже с Приветом
Posts: 4637 Joined: 24 Oct 2009 01:38
Location: Chicago ;-) -> SFBA!
Post
by crypto5 » 12 Feb 2014 09:20
Интеррапт wrote: crypto5 wrote: Интеррапт wrote: crypto5 wrote: А вот если окажется что барберов 10, то мне нужно будет одну цифру поменять, а ты будешь плодить баги и дедлоки
Просто тебе стыдно стало, что ты кучу потоков развел на ровном месте. Джавис, что тут скажешь.
Столько же сколько и ты развел
Да я даже не про этот конкретный случай, а про F/J Pool c I/O операциями
Ну твоего "малопоточного" кода я так и не увидел
In vino Veritas!
crypto5
Интеррапт
Уже с Приветом
Posts: 17281 Joined: 07 Sep 2011 10:05
Location: Seattle, WA
Post
by Интеррапт » 12 Feb 2014 10:04
А я уже показал псевдокод и обьяснил концепцию. Обычный асинхронный read без выкрутасов.
Интеррапт
crypto5
Уже с Приветом
Posts: 4637 Joined: 24 Oct 2009 01:38
Location: Chicago ;-) -> SFBA!
Post
by crypto5 » 12 Feb 2014 10:06
Интеррапт wrote: А я уже показал псевдокод и обьяснил концепцию. Обычный асинхронный read без выкрутасов.
Я думаю если ты начнешь его реализовывать то обнаружишь что выкрутасы там присутствуют.
In vino Veritas!
crypto5
Интеррапт
Уже с Приветом
Posts: 17281 Joined: 07 Sep 2011 10:05
Location: Seattle, WA
Post
by Интеррапт » 12 Feb 2014 10:51
crypto5 wrote: Интеррапт wrote: А я уже показал псевдокод и обьяснил концепцию. Обычный асинхронный read без выкрутасов.
Я думаю если ты начнешь его реализовывать то обнаружишь что выкрутасы там присутствуют.
Вряд-ли обнаружу. Все очень просто и логично.
Интеррапт
Zorkus
Уже с Приветом
Posts: 6969 Joined: 26 Feb 2011 17:40
Post
by Zorkus » 12 Feb 2014 11:15
Бенчмарки-то где?
Zorkus
crypto5
Уже с Приветом
Posts: 4637 Joined: 24 Oct 2009 01:38
Location: Chicago ;-) -> SFBA!
Post
by crypto5 » 12 Feb 2014 18:05
Интеррапт wrote: crypto5 wrote: Интеррапт wrote: А я уже показал псевдокод и обьяснил концепцию. Обычный асинхронный read без выкрутасов.
Я думаю если ты начнешь его реализовывать то обнаружишь что выкрутасы там присутствуют.
Вряд-ли обнаружу. Все очень просто и логично.
Ненаписанный код всегда такой
In vino Veritas!
crypto5
Berlaga
Уже с Приветом
Posts: 1008 Joined: 24 Mar 2010 21:14
Location: SFBA
Post
by Berlaga » 12 Feb 2014 19:42
crypto5 wrote: Интеррапт wrote:
Вряд-ли обнаружу. Все очень просто и логично.
Ненаписанный код всегда такой
В точку.
Berlaga
Leo_G
Уже с Приветом
Posts: 576 Joined: 15 Jan 2005 06:08
Location: Samara -> Vancouver, CAN
Post
by Leo_G » 13 Feb 2014 02:39
Sergunka wrote: Так уж вышло, что
получив неделю бана решил с пользой для себе провести время и начать вести ИТ блог.
Без особых заморочек пришлось взять поначалу наиболее прстую схему изложения в духе еду-вижу максимально напирая на знания и детали работающего кода. Из движков вроде как мне подошел WordPress.com с довольно простенькой и эффективной заяснялкой как оформлять код на станице
http://en.support.wordpress.com/code/po ... urce-code/
Если совсем коротко то за неделю удалось написать три статьи, что видимо эквивалентно десятку другому постов на привете
Собственно сам блог
http://vyatkins.wordpress.com/ - если читать лень, то кликните накрутите пейджинг
Если кто ведет свой собственный блог в ИТ было бы неплохо обменятся опытом и послушать людей бывалых
Из очевидных преимуществ блога вижу пока две - можно показать свой уровень изложения + понимание специальной области, что как ни-крути должно характеризовать кандидата на позицию с лучшей стороны... ну, хотя бы положительно, что не ленив
и жаден
И все... блог уже заброшен??
Вот взять бы всю парикмахерскую дискуссию отсюда и запостить в блог. Будет очень интересно. И делать особо ничего не надо, копи-паст.
Блог живой нужен.
Biztalkien
Leo_G
Мальчик-Одуванчик
Уже с Приветом
Posts: 15526 Joined: 27 Sep 2007 22:53
Post
by Мальчик-Одуванчик » 13 Feb 2014 03:06
Ага а потом еще немножко усложнить задачку разрешив одному парикмахеру обслуживать нескольких посетителей
Мальчик-Одуванчик
AxelA
Новичок
Posts: 46 Joined: 23 Apr 2011 18:43
Location: WA
Post
by AxelA » 13 Feb 2014 03:16
Интеррапт wrote: Ну раз пошла такая пьянка, то и мы парикмахера напишем:
Гулять так гулять. Достаем из шир.. то есть тяжелую артилерию.
C++ с модными 11x свистелками и перделками.
Code: Select all
#include <stdio.h>
#include <atomic>
#include <condition_variable>
#include <deque>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
using namespace std;
class Barber;
class Client;
class Shop;
typedef shared_ptr<Client> ClientPtr;
static const int NUM_CHAIRS = 5;
static const int NUM_CLIENT_THREADS = 20;
static chrono::milliseconds BARBER_SESSION_TIME(50);
static chrono::milliseconds PAUSE_BETWEEN_CLIENTS(200);
class Client
{
public:
const int _id;
Client(int id) : _id(id) {};
};
class Shop
{
public:
bool Serve(ClientPtr client)
{
lock_guard<mutex> guard(_lock);
if (!_waitLine.empty() || _chair != nullptr)
{
if (_waitLine.size() >= NUM_CHAIRS)
{
printf("Client %d left unsatisfied.\n", client->_id);
return false;
}
_waitLine.push(client);
printf("Client %d is wating.\n", client->_id);
}
else
{
assert(_chair == nullptr);
_chair = client;
printf("Client %d is about to be served.\n", client->_id);
}
_signal.notify_one();
return true;
}
private:
friend class Barber;
ClientPtr GetNextClient()
{
while (true)
{
unique_lock<mutex> guard(_lock);
if (_chair == nullptr && !_waitLine.empty())
{
_chair = _waitLine.front();
_waitLine.pop();
}
if (_chair != nullptr)
{
return _chair;
}
printf("Barber is sleeping.\n");
_signal.wait(guard);
printf("Barber wakes up.\n");
}
}
void DoneWithClient()
{
lock_guard<mutex> guard(_lock);
assert(_chair != nullptr);
_chair = nullptr;
if (!_waitLine.empty())
{
_signal.notify_one();
}
}
mutex _lock;
condition_variable _signal;
queue<ClientPtr> _waitLine;
ClientPtr _chair;
};
class Barber
{
public:
Barber(Shop& shop) : _shop(shop) {};
void run()
{
while (true)
{
ClientPtr client = _shop.GetNextClient();
CutEverything(client);
_shop.DoneWithClient();
}
}
private:
void CutEverything(ClientPtr client)
{
printf("Serving client#%d.\n", client->_id);
this_thread::sleep_for(BARBER_SESSION_TIME);
}
Shop& _shop;
};
static void ClientThread(Shop* shop)
{
static atomic_int clientID;
while (true)
{
ClientPtr client = make_shared<Client>(clientID++);
shop->Serve(client);
this_thread::sleep_for(PAUSE_BETWEEN_CLIENTS);
}
}
static void BarberThread(Shop* shop)
{
Barber barber(*shop);
barber.run();
}
static void test()
{
Shop shop;
thread barberThread(&BarberThread, &shop);
thread clientThreads[NUM_CLIENT_THREADS];
for (int i = 0; i < NUM_CLIENT_THREADS; i++)
{
clientThreads[i] = thread(ClientThread, &shop);
}
this_thread::sleep_for(chrono::hours(1000));
}
void main()
{
test();
}
AxelA