diff --git a/include/mutexs.h b/include/mutexs.h
index c227ff4..c56790e 100644
--- a/include/mutexs.h
+++ b/include/mutexs.h
@@ -53,6 +53,10 @@
 #	define ZBX_MUTEX_PROXY_HISTORY	13
 #	define ZBX_MUTEX_COUNT		14
 
+#	define ZBX_RWLOCK_CONFIG	0
+#	define ZBX_RWLOCK_VALUECACHE	1
+#	define ZBX_RWLOCK_COUNT		2
+
 #endif	/* _WINDOWS */
 
 #define zbx_mutex_lock(mutex)			__zbx_mutex_lock(__FILE__, __LINE__, mutex)
@@ -67,4 +71,9 @@ void	zbx_mutex_destroy(ZBX_MUTEX *mutex);
 ZBX_MUTEX_NAME	zbx_mutex_create_per_process_name(const ZBX_MUTEX_NAME prefix);
 #endif
 
+void	zbx_init_mutexes();
+void	zbx_rwlock_wrlock(int rwlock);
+void	zbx_rwlock_rdlock(int rwlock);
+void	zbx_rwlock_unlock(int rwlock);
+
 #endif	/* ZABBIX_MUTEXS_H */
diff --git a/src/libs/zbxdbcache/dbconfig.c b/src/libs/zbxdbcache/dbconfig.c
index 0d06c0d..7b5fdbf 100644
--- a/src/libs/zbxdbcache/dbconfig.c
+++ b/src/libs/zbxdbcache/dbconfig.c
@@ -41,8 +41,9 @@
 
 static int	sync_in_progress = 0;
 
-#define	LOCK_CACHE	if (0 == sync_in_progress) zbx_mutex_lock(&config_lock)
-#define	UNLOCK_CACHE	if (0 == sync_in_progress) zbx_mutex_unlock(&config_lock)
+#define	LOCK_CACHE	if (0 == sync_in_progress) zbx_rwlock_wrlock(ZBX_RWLOCK_CONFIG)
+#define	RDLOCK_CACHE	if (0 == sync_in_progress) zbx_rwlock_rdlock(ZBX_RWLOCK_CONFIG)
+#define	UNLOCK_CACHE	if (0 == sync_in_progress) zbx_rwlock_unlock(ZBX_RWLOCK_CONFIG)
 #define START_SYNC	LOCK_CACHE; sync_in_progress = 1
 #define FINISH_SYNC	sync_in_progress = 0; UNLOCK_CACHE
 
@@ -6126,7 +6127,7 @@ void	DCconfig_get_items_by_keys(DC_ITEM *items, zbx_host_key_t *keys, int *errco
 	const ZBX_DC_ITEM	*dc_item;
 	const ZBX_DC_HOST	*dc_host;
 
-	LOCK_CACHE;
+	RDLOCK_CACHE;
 
 	for (i = 0; i < num; i++)
 	{
@@ -6165,7 +6166,7 @@ void	DCconfig_get_items_by_itemids(DC_ITEM *items, const zbx_uint64_t *itemids,
 	const ZBX_DC_ITEM	*dc_item;
 	const ZBX_DC_HOST	*dc_host;
 
-	LOCK_CACHE;
+	RDLOCK_CACHE;
 
 	for (i = 0; i < num; i++)
 	{
diff --git a/src/libs/zbxsys/mutexs.c b/src/libs/zbxsys/mutexs.c
index a55744c..ee3b34a 100644
--- a/src/libs/zbxsys/mutexs.c
+++ b/src/libs/zbxsys/mutexs.c
@@ -20,6 +20,7 @@
 #include "common.h"
 #include "log.h"
 #include "mutexs.h"
+#include "memalloc.h"
 
 #ifndef _WINDOWS
 #	if !HAVE_SEMUN
@@ -42,6 +43,27 @@
 	static unsigned char	mutexes = 0;
 #endif
 
+#define ZBX_PTHREAD
+
+#ifdef ZBX_PTHREAD
+
+typedef struct
+{
+	pthread_mutex_t		mutexes[ZBX_MUTEX_COUNT];
+	pthread_rwlock_t	rwlocks[ZBX_RWLOCK_COUNT];
+}
+zbx_lock_t;
+
+static zbx_lock_t	*lock;
+
+static zbx_mem_info_t	*mutex_mem;
+
+ZBX_MEM_FUNC_IMPL(__mtx, mutex_mem);
+
+extern char	*CONFIG_FILE;
+#endif
+
+
 /******************************************************************************
  *                                                                            *
  * Function: zbx_mutex_create                                                 *
@@ -66,6 +88,16 @@ int	zbx_mutex_create(ZBX_MUTEX *mutex, ZBX_MUTEX_NAME name, char **error)
 		return FAIL;
 	}
 #else
+#ifdef	ZBX_PTHREAD
+	pthread_mutexattr_t	mta;
+
+	pthread_mutexattr_init(&mta);
+	pthread_mutexattr_setpshared(&mta, PTHREAD_PROCESS_SHARED);
+	pthread_mutexattr_setrobust(&mta, PTHREAD_MUTEX_ROBUST);
+	pthread_mutex_init(&lock->mutexes[name], &mta);
+	*mutex = name;
+#else
+
 	if (-1 == ZBX_SEM_LIST_ID)
 	{
 		union semun	semopts;
@@ -99,6 +131,7 @@ int	zbx_mutex_create(ZBX_MUTEX *mutex, ZBX_MUTEX_NAME name, char **error)
 	*mutex = name;
 	mutexes++;
 #endif
+#endif
 	return SUCCEED;
 }
 
@@ -140,6 +173,9 @@ void	__zbx_mutex_lock(const char *filename, int line, ZBX_MUTEX *mutex)
 			exit(EXIT_FAILURE);
 	}
 #else
+#ifdef	ZBX_PTHREAD
+	pthread_mutex_lock(&lock->mutexes[*mutex]);
+#else
 	sem_lock.sem_num = *mutex;
 	sem_lock.sem_op = -1;
 	sem_lock.sem_flg = SEM_UNDO;
@@ -153,6 +189,7 @@ void	__zbx_mutex_lock(const char *filename, int line, ZBX_MUTEX *mutex)
 		}
 	}
 #endif
+#endif
 }
 
 /******************************************************************************
@@ -183,6 +220,9 @@ void	__zbx_mutex_unlock(const char *filename, int line, ZBX_MUTEX *mutex)
 		exit(EXIT_FAILURE);
 	}
 #else
+#ifdef	ZBX_PTHREAD
+	pthread_mutex_unlock(&lock->mutexes[*mutex]);
+#else
 	sem_unlock.sem_num = *mutex;
 	sem_unlock.sem_op = 1;
 	sem_unlock.sem_flg = SEM_UNDO;
@@ -196,6 +236,7 @@ void	__zbx_mutex_unlock(const char *filename, int line, ZBX_MUTEX *mutex)
 		}
 	}
 #endif
+#endif
 }
 
 /******************************************************************************
@@ -218,9 +259,13 @@ void	zbx_mutex_destroy(ZBX_MUTEX *mutex)
 	if (0 == CloseHandle(*mutex))
 		zbx_error("error on mutex destroying: %s", strerror_from_system(GetLastError()));
 #else
+#ifdef	ZBX_PTHREAD
+	pthread_mutex_destroy(&lock->mutexes[*mutex]);
+#else
 	if (0 == --mutexes && -1 == semctl(ZBX_SEM_LIST_ID, 0, IPC_RMID, 0))
 		zbx_error("cannot remove semaphore set %d: %s", ZBX_SEM_LIST_ID, zbx_strerror(errno));
 #endif
+#endif
 	*mutex = ZBX_MUTEX_NULL;
 }
 
@@ -263,3 +308,57 @@ ZBX_MUTEX_NAME  zbx_mutex_create_per_process_name(const ZBX_MUTEX_NAME prefix)
 	return name;
 }
 #endif
+
+void	zbx_init_mutexes()
+{
+#ifdef ZBX_PTHREAD
+
+	int			i;
+	key_t			shm_key;
+	pthread_rwlockattr_t	rwa;
+	char			*error = NULL;
+
+	if (FAIL == zbx_mem_create(&mutex_mem, sizeof(zbx_lock_t) + zbx_mem_required_size(1, "Shared mutexes", "MutexSize"),
+			"Shared mutexes", "MutexSize", 0, &error))
+	{
+		zbx_error("failed to create shared memory segment for mutex");
+	}
+
+	lock = __mtx_mem_malloc_func(NULL,  sizeof(zbx_lock_t));
+	memset(lock, 0,  sizeof(zbx_lock_t));
+
+	pthread_rwlockattr_init(&rwa);
+	pthread_rwlockattr_setpshared(&rwa, PTHREAD_PROCESS_SHARED);
+
+	for (i = 0; i < ZBX_RWLOCK_COUNT; i++)
+	{
+		if (0 != pthread_rwlock_init(&lock->rwlocks[i], &rwa))
+			zbx_error("failed to create rw lock");
+	}
+
+#endif
+}
+
+
+void	zbx_rwlock_wrlock(int rwlock)
+{
+#ifdef	ZBX_PTHREAD
+	pthread_rwlock_wrlock(&lock->rwlocks[rwlock]);
+#endif
+}
+
+void	zbx_rwlock_rdlock(int rwlock)
+{
+#ifdef	ZBX_PTHREAD
+	pthread_rwlock_rdlock(&lock->rwlocks[rwlock]);
+#endif
+}
+
+void	zbx_rwlock_unlock(int rwlock)
+{
+#ifdef	ZBX_PTHREAD
+	pthread_rwlock_unlock(&lock->rwlocks[rwlock]);
+#endif
+}
+
+
diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c
index 61435b7..d83d0db 100644
--- a/src/zabbix_server/server.c
+++ b/src/zabbix_server/server.c
@@ -814,6 +814,8 @@ int	main(int argc, char **argv)
 	if (NULL == CONFIG_FILE)
 		CONFIG_FILE = zbx_strdup(NULL, DEFAULT_CONFIG_FILE);
 
+	zbx_init_mutexes();
+
 	/* required for simple checks */
 	init_metrics();
 
