[pthread] RWlock

      Comments Off on [pthread] RWlock

Reader-writer problem
https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem
Suppose we have a shared memory area with the basic constraints detailed above. It is possible to protect the shared data behind a mutual exclusion mutex, in which case no two threads can access the data at the same time. However, this solution is suboptimal ( Không tối ưu), because it is possible that a reader R1 might have the lock, and then another reader R2 requests access. It would be foolish for R2 to wait until R1 was done before starting its own read operation; instead, R2 should be allowed to read the resource alongside R1 because reads don’t modify data, so concurrent reads are safe. This is the motivation for the first readers-writers problem, in which the constraint is added that no reader shall be kept waiting if the share is currently opened for reading. This is also called readers-preference, with its solution:

==> Cần cho phép đọc song song ( non-blocking). Nếu có writer thì mọi reader and writer khác đều bị block lại.

ví dụ:

#define HAVE_STRUCT_TIMESPEC
#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h>
#include <windows.h>
pthread_rwlock_t rwlock;

void * write(void *temp) {
	char *ret;
	FILE *file1;
	char *str;
	ret = (char*)pthread_rwlock_wrlock(&rwlock);
	printf("\nFile locked 1, please enter the message \n");
	str = (char *)malloc(10 * sizeof(char));
	file1 = fopen("temp", "w");
	scanf("%s", str);
	fprintf(file1, "%s", str);
	fclose(file1);
	pthread_rwlock_unlock(&rwlock);
	printf("\nUnlocked 1 the file you can read it now \n");
	return ret;
}




void * write_2(void *temp) {
	char *ret;
	FILE *file1;
	char *str;
	Sleep(3);
	ret = (char*)pthread_rwlock_wrlock(&rwlock);
	printf("\nFile locked 2, please enter the message \n");
	str = (char *)malloc(10 * sizeof(char));
	file1 = fopen("temp", "a");
	scanf("%s", str);
	fprintf(file1, "%s", str);
	fclose(file1);
	pthread_rwlock_unlock(&rwlock);
	printf("\nUnlocked 2 the file you can read it now \n");
	return ret;
}





void * read_1(void *temp) {
	char *ret;
	FILE *file1;
	char *str;
	Sleep(5);
	pthread_rwlock_rdlock(&rwlock);
	printf("\n1 Opening file for reading1\n");
	file1 = fopen("temp", "r");
	str = (char *)malloc(10 * sizeof(char));
	fscanf(file1, "%s", str);
	printf("\nMessage from file is %s \n", str);
	Sleep(3);

	fclose(file1);
	printf("\nUnlocking rwlock\n");
	pthread_rwlock_unlock(&rwlock);
	return NULL;
}





void * read_2(void *temp) {
	char *ret;
	FILE *file1;
	char *str;
	Sleep(6);
	pthread_rwlock_rdlock(&rwlock);
	printf("\n2 Opening file for reading2\n");
	file1 = fopen("temp", "r");
	str = (char *)malloc(10 * sizeof(char));
	fscanf(file1, "%s", str);
	printf("\nMessage from file is %s \n", str);

	fclose(file1);

	pthread_rwlock_rdlock(&rwlock);

	return NULL;
}




int main() {

	pthread_t thread_id, thread_id1, thread_id3, thread_id4;
	pthread_attr_t attr;
	int ret;
	void *res;
	pthread_rwlock_init(&rwlock, NULL);
	ret = pthread_create(&thread_id, NULL, &write, NULL);
	ret = pthread_create(&thread_id1, NULL, &read_1, NULL);

	ret = pthread_create(&thread_id3, NULL, &read_2, NULL);

	ret = pthread_create(&thread_id4, NULL, &write_2, NULL);
	printf("\n Created thread");
	pthread_join(thread_id, &res);
	pthread_join(thread_id1, &res);
	pthread_join(thread_id3, &res);

	pthread_join(thread_id4, &res);
	pthread_rwlock_destroy(&rwlock);
	return 0;
}