diff --git a/configure b/configure
index 0e537d9..f11cccf 100755
--- a/configure
+++ b/configure
@@ -18923,7 +18923,8 @@ fi
 
 
 
-for ac_func in cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit memmove poll pstat readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l
+
+for ac_func in cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit memmove poll pstat random_r readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/configure.in b/configure.in
index 150f9a5..fc1e73a 100644
--- a/configure.in
+++ b/configure.in
@@ -1192,7 +1192,7 @@ PGAC_VAR_INT_TIMEZONE
 AC_FUNC_ACCEPT_ARGTYPES
 PGAC_FUNC_GETTIMEOFDAY_1ARG
 
-AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit memmove poll pstat readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l])
+AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit memmove poll pstat random_r readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l])
 
 AC_REPLACE_FUNCS(fseeko)
 case $host_os in
diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index 9892f4c..751deb1 100644
--- a/contrib/pgbench/pgbench.c
+++ b/contrib/pgbench/pgbench.c
@@ -104,6 +104,8 @@ extern int	optind;
 
 #define DEFAULT_NXACTS	10		/* default nxacts */
 
+#define RAND_STATE_BYTES 128	/* glibc supports powers of 2, 8 .. 256 */
+
 int			nxacts = 0;			/* number of transactions per client */
 int			duration = 0;		/* duration in seconds */
 
@@ -198,6 +200,10 @@ typedef struct
 	instr_time	start_time;		/* thread start time */
 	instr_time *exec_elapsed;	/* time spent executing cmds (per Command) */
 	int		   *exec_count;		/* number of cmd executions (per Command) */
+#ifdef HAVE_RANDOM_R
+	char		randstate[RAND_STATE_BYTES];	/* random state */
+	struct random_data	randbuf;				/* random data buffer */
+#endif
 } TState;
 
 #define INVALID_THREAD		((pthread_t) 0)
@@ -380,13 +386,21 @@ usage(const char *progname)
 
 /* random number generator: uniform distribution from min to max inclusive */
 static int
-getrand(int min, int max)
+getrand(TState *thread, int min, int max)
 {
+#ifdef HAVE_RANDOM_R
+	int32_t	raw;
+	random_r(&thread->randbuf, &raw);
+#else
+	long	raw;
+	raw = random();
+#endif
+
 	/*
 	 * Odd coding is so that min and max have approximately the same chance of
 	 * being selected as do numbers between them.
 	 */
-	return min + (int) (((max - min + 1) * (double) random()) / (MAX_RANDOM_VALUE + 1.0));
+	return min + (int) (((max - min + 1) * (double) raw) / (MAX_RANDOM_VALUE + 1.0));
 }
 
 /* call PQexec() and exit() on failure */
@@ -901,7 +915,7 @@ top:
 		if (commands[st->state] == NULL)
 		{
 			st->state = 0;
-			st->use_file = getrand(0, num_files - 1);
+			st->use_file = getrand(thread, 0, num_files - 1);
 			commands = sql_files[st->use_file];
 		}
 	}
@@ -1068,9 +1082,9 @@ top:
 			}
 
 #ifdef DEBUG
-			printf("min: %d max: %d random: %d\n", min, max, getrand(min, max));
+			printf("min: %d max: %d random: %d\n", min, max, getrand(thread, min, max));
 #endif
-			snprintf(res, sizeof(res), "%d", getrand(min, max));
+			snprintf(res, sizeof(res), "%d", getrand(thread, min, max));
 
 			if (!putVariable(st, argv[0], argv[1], res))
 			{
@@ -2242,6 +2256,15 @@ main(int argc, char **argv)
 		thread->tid = i;
 		thread->state = &state[nclients / nthreads * i];
 		thread->nstate = nclients / nthreads;
+#ifdef HAVE_RANDOM_R
+		/* glibc gets confused if we don't zero these */
+		memset(thread->randstate, 0, RAND_STATE_BYTES);
+		memset(&thread->randbuf, 0, sizeof(thread->randbuf));
+		initstate_r(((unsigned int) INSTR_TIME_GET_MICROSEC(start_time)) +
+					((unsigned int) i),
+					thread->randstate, RAND_STATE_BYTES,
+					&thread->randbuf);
+#endif
 
 		if (is_latencies)
 		{
@@ -2384,7 +2407,7 @@ threadRun(void *arg)
 		Command   **commands = sql_files[st->use_file];
 		int			prev_ecnt = st->ecnt;
 
-		st->use_file = getrand(0, num_files - 1);
+		st->use_file = getrand(thread, 0, num_files - 1);
 		if (!doCustom(thread, st, &result->conn_time, logfile))
 			remains--;			/* I've aborted */
 
@@ -2590,9 +2613,11 @@ pthread_create(pthread_t *thread,
 	 * output of a single random() sequence, which should be okay for our
 	 * purposes.)
 	 */
+#ifndef HAVE_RANDOM_R
 	INSTR_TIME_SET_CURRENT(start_time);
 	srandom(((unsigned int) INSTR_TIME_GET_MICROSEC(start_time)) +
 			((unsigned int) getpid()));
+#endif
 
 	ret = start_routine(arg);
 	write(th->pipes[1], ret, sizeof(TResult));
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 24b951e..8e87667 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -405,6 +405,9 @@
 /* Define to 1 if you have the `random' function. */
 #undef HAVE_RANDOM
 
+/* Define to 1 if you have the `random_r' function. */
+#undef HAVE_RANDOM_R
+
 /* Define to 1 if you have the <readline.h> header file. */
 #undef HAVE_READLINE_H
 
