读写锁

读写锁

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <list>

bool quitting = false;
int data = 0;

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP;

class Reader {
	int id_;
	pthread_t thread_;

public:
	explicit Reader(int id)
		id_(id)
	{
		pthread_create(&thread_, nullptr, &Reader::_run, this);
	}

	~Reader() {
		pthread_join(thread_, nullptr);
	}

	void run() {
		while (!quitting) {
			pthread_rwlock_rdlock(&rwlock);
			printf("[%d]: %d\n", id_, data);
			pthread_rwlock_unlock(&rwlock);

			pthread_yield(); // junk
		}
	}

private:
	static void* _run(void* p) {
		Reader* reader = static_cast<Reader*>(p);
		reader->run();
		return nullptr;
	}
};

void writer() {
	pthread_yield();
	for (;;) {
		sleep(1);

		printf("rwlock: Acquiring for WRITE\n");
		pthread_rwlock_wrlock(&rwlock);
		printf("rwlock: hardcore WRITE-action @.@ BEGIN\n");
		data = data + 1;
		quitting = data == 42;
		sleep(2);
		printf("rwlock: hardcore WRITE-action @.@ DONE\n");
		pthread_rwlock_unlock(&rwlock);
	}
}

int main(int argc, const char *argv[])
{
	srand(time(nullptr));

	std::list<Reader*> readers;

	for (int i = 1, e = (argc == 2 ? atoi(argv[1]) : 4); i <= e; ++i)
		readers.push_back(new Reader(i));

	writer();

	for (auto reader: readers)
		delete reader;

	return 0;
}
struct rwlock
{
    volatile uint32_t state;
};

static void __rwlock_init(struct rwlock *lock)
{
    lock->state = 0;
}

static void __read_lock(struct rwlock *lock)
{
    unsigned int new_state;
    unsigned int expected;
    do
    {
        expected = lock->state & 0xffff; /* I expect no write lock */
        new_state = expected + 1;        /* Add me as reader */
    } while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));
}

static void __read_unlock(struct rwlock *lock)
{
    unsigned int new_state;
    unsigned int expected;
    do
    {
        expected = lock->state;   /* I expect a write lock and other readers */
        new_state = expected - 1; /* Drop me as reader */
    } while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));
}

static void __write_lock(struct rwlock *lock)
{
    unsigned int new_state;
    unsigned int expected;
    do
    {
        expected = lock->state & 0xffff;  /* I expect some 0+ readers */
        new_state = (1 << 16) | expected; /* I want to lock the other writers */
    } while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));

    /* Wait pending reads */
    while ((lock->state & 0xffff) > 0) /* cpu_relax(); */
        ;
}

static void __write_unlock(struct rwlock *lock)
{
    unsigned int new_state;
    unsigned int expected;
    do
    {
        expected = 1 << 16; /* I expect to be the only writer */
        new_state = 0;      /* reset: no writers/no readers */
    } while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));
}
上一页
下一页