Program is not generating random number and I am not sure why - c

#include<pthread.h>
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<time.h>
#include<unistd.h>
#define ERROR_CREATE 1
#define ERROR_JOIN 2
// create the function to be executed as a thread
void *thread(void *ptr)
{
uintptr_t type = (uintptr_t) ptr; // thread number
srand(time(NULL) + getpid());
int wait = rand() % 10; // randomizes numbers from 0 to 10
sleep(wait); // waits in time intervals of seconds
printf("Thread - %ld waiting for %d seconds\n",type, wait);
return ptr; // returns the thread number
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Error with command line arguments");
}
int num_threads = atoi(argv[1]);
pthread_t threads[num_threads]; // array of thread types
for (long i = 1; i <= num_threads; i++) {
if (pthread_create(&threads[i], NULL, thread, (void *)i) != 0)
// if there's an error creating thread
{
fprintf(stderr,"Error: could not create thread");
return ERROR_CREATE;
}
}
// terminate each thread assigned
for (int i = 1; i <= num_threads; i++) {
if (pthread_join(threads[i], NULL) != 0)
// if there's an error ending each thread
{
fprintf(stderr, "Error: could not terminate thread");
return ERROR_JOIN;
}
}
return 0;
}
Seeding the rand function, I am still getting the same number outputted. I understand the hardware is fast and therefore is getting the same answer as the clock speed is faster than seeding the rand function. Does anyone know another way of getting more variety from the rand function?

Return if argv[1] is not populated otherwise it segfaults.
srand() resets the sequence. As you call it multiple times with the same value this is not what you want. Moved it main().
The array threads is accessed out of bounds in the two loops.
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#define ERROR_CREATE 1
#define ERROR_JOIN 2
// create the function to be executed as a thread
void *thread(void *ptr) {
uintptr_t type = (uintptr_t) ptr; // thread number
int wait = rand() % 10; // randomizes numbers from 0 to 10
sleep(wait); // waits in time intervals of seconds
printf("Thread - %ld waiting for %d seconds\n",type, wait);
return ptr; // returns the thread number
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Error with command line arguments\n");
return 1;
}
srand(time(NULL));
int num_threads = atoi(argv[1]);
pthread_t threads[num_threads]; // array of thread types
for (long i = 0; i < num_threads; i++) {
if (pthread_create(&threads[i], NULL, thread, (void *)i) != 0)
// if there's an error creating thread
{
fprintf(stderr,"Error: could not create thread");
return ERROR_CREATE;
}
}
// terminate each thread assigned
for (int i = 0; i < num_threads; i++) {
if (pthread_join(threads[i], NULL) != 0)
// if there's an error ending each thread
{
fprintf(stderr, "Error: could not terminate thread");
return ERROR_JOIN;
}
}
}
and here is a couple of sample runs:
$ ./a.out 2
Thread - 1 waiting for 3 seconds
Thread - 2 waiting for 7 seconds
$ ./a.out 2
Thread - 1 waiting for 3 seconds
Thread - 2 waiting for 6 seconds

Related

error occured when using function sem_init

I'm using Linux to learn semaphore, trnna test the function sem_init. The code seems simple but the error is unexpected, don't know why. Here's the code and the errors is below the code.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include<unistd.h>
#include <stdlib.h>
#define NITER 1000000
int cnt = 0;
sem_t mutex;
sem_init(&mutex,0,1);
void * Count(void * a)
{
int i, tmp;
for(i = 0; i < NITER; i++)
{
sem_wait(&mutex);
tmp = cnt; /* copy the global cnt locally */
tmp = tmp+1; /* increment the local copy */
cnt = tmp; /* store the local value into the global cnt */
sem_post(&mutex);
}
}
int main(int argc, char * argv[])
{
pthread_t tid1, tid2;
if(pthread_create(&tid1, NULL, Count, NULL))
{
printf("\n ERROR creating thread 1");
exit(1);
}
if(pthread_create(&tid2, NULL, Count, NULL))
{
printf("\n ERROR creating thread 2");
exit(1);
}
if(pthread_join(tid1, NULL)) /* wait for the thread 1 to finish */
{
printf("\n ERROR joining thread");
exit(1);
}
if(pthread_join(tid2, NULL)) /* wait for the thread 2 to finish */
{
printf("\n ERROR joining thread");
exit(1);
}
if (cnt < 2 * NITER)
printf("\n BOOM! cnt is [%d], should be %d\n", cnt, 2*NITER);
else
printf("\n OK! cnt is [%d]\n", cnt);
pthread_exit(NULL);
}
my english is bad, if anything is hard to understand please tell me and ill respond you as soon as possible!thx
You can declare variables outside the main and the other function which mean that the variable is global .
But to call the function sem_init(&mutex,0,1); you should do it from the main or from another function. In your case , you have to do it in the main.
After moving the sem_init inside the main it compile
nabil#DESKTOP-8ECTID4:~/stackoverflow$ gcc bad.c -o bad -lpthread
nabil#DESKTOP-8ECTID4:~/stackoverflow$

Issue with Threading in C for Linux

Here is what I need to do:
Write a pthread program that takes an integer command line argument n,
spawns n threads that will each generate a random numbers between -100
and 100, and then computes and prints out the sum of these random
numbers. Each thread needs to print out the random number it
generates.
Here is what I have:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
int randomNum=0;
int randomSum=0;
void *randomNumberGenerator(void *id){
int *myid = (int *)id;
randomNum = rand()% 201 + (-100);
printf("%d\n", randomNum);
randomSum+=randomNum;
}
int main (int argc , char *argv[]){
int command;
char *strNumThreads = NULL;
int i;
while((command = getopt(argc, argv, "n:"))!=-1){
if(command == 'n'){
strNumThreads = optarg;
break;
}
}
int numThreads = atoi(strNumThreads);
pthread_t thread;
int newThread;
for(i = 0; i<numThreads; i++){
srand(time(NULL));
pthread_create(&thread, NULL, randomNumberGenerator, (void*)i);
}
pthread_exit(NULL);
printf("%d\n" , randomSum);
return 0;
}
For some reason randomSum is not getting printed.
randomNum is a variable that is shared among all threads, so you need a mutex
when you access the variable, because randomSum+=randomNum; is not an atomic
operation. The current process might get interrupted and another process is
scheduled which changes both variables. When the interrupted process resumes, it
will overwrite randomNum and you end up with garbage.
Also you have to wait for all threads to finish until you print the sum. For
that you have to execute pthread_wait.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
// can be a global variable
int randomSum=0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *randomNumberGenerator(void *id){
int randomNum=0; // does not need to be a global variable
randomNum = rand()% 201 + (-100);
printf("%d\n", randomNum);
pthread_mutex_lock(&mutex);
randomSum+=randomNum;
pthread_mutex_unlock(&mutex);
pthread_exit(0);
}
int main (int argc , char *argv[]){
int command;
char *strNumThreads = NULL;
int i;
while((command = getopt(argc, argv, "n:"))!=-1){
if(command == 'n'){
strNumThreads = optarg;
break;
}
}
// initializing the randomizer
srand(time(NULL));
int numThreads = atoi(strNumThreads);
if(numThreads == 0)
{
fprintf(stderr, "Invalid number of threads\n");
return 1;
}
pthread_t threads[numThreads];
for(i = 0; i<numThreads; i++){
pthread_create(threads + i, NULL, randomNumberGenerator, NULL);
}
for(i = 0; i < numThreads; ++i)
pthread_join(threads[i], NULL);
printf("%d\n" , randomSum);
return 0;
}
You really need to learn how to use the libraries you are using. pthread_exit
must be used by the threads to tell the system "I'm finished", calling it in the
main thread makes no sense.
pthread_create(&thread, NULL, randomNumberGenerator, (void*)i);
I consider this an uggly hack, what you should do is create an array with the
ids of the threads and pass every thread a pointer to its id, like this:
int ids[numThreads];
for(i = 0; i<numThreads; i++){
ids[i] = i;
pthread_create(&thread, NULL, randomNumberGenerator, ids+i);
}
and in the thread you can do
void *randomNumberGenerator(void *idp) {
int *id = idp;
printf("My thread id is %d\n", *id);
...
pthread_exit(NULL);
}
And if your worker threads are just calculating a value, you can use
pthread_exit to return that value back to the main thread. For example:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
struct thdata {
int id;
int random;
};
void *randomNumberGenerator(void *data) {
struct thdata *ret = data;
ret->random = rand()% 201 + (-100);
printf("thread with id %d: random %d\n", ret->id, ret->random);
pthread_exit(data);
}
int main (int argc , char *argv[]){
int i;
// initializing the randomizer
srand(time(NULL));
int numThreads = 5;
if(numThreads == 0)
{
fprintf(stderr, "Invalid number of threads\n");
return 1;
}
pthread_t threads[numThreads];
struct thdata data[numThreads];
for(i = 0; i<numThreads; i++){
data[i].id = i;
pthread_create(threads + i, NULL, randomNumberGenerator, data+i);
}
int randomSum = 0;
for(i = 0; i < numThreads; ++i)
{
struct thdata *data;
pthread_join(threads[i], (void**) &data);
randomSum += data->random;
}
printf("The sum of the random values is: %d\n" , randomSum);
return 0;
}
Which gives me the output (for 5 threads):
thread with id 0: random 72
thread with id 4: random -94
thread with id 1: random 1
thread with id 2: random -74
thread with id 3: random 42
The sum of the random values is: -53
You currently have a data race in place, because you have multiple threads accessing randomSum concurrently. Here's a solution, with comments, using Mutexes to solve the problem.
Note how using a struct to hold the sum and it's mutex allows us to get rid of all globals.
As a plus, I replaced your random generator with a proper one on POSIX systems. Note that your multiple calls to srand() are wrong, and cause less randomicity. You should only ever call srand() once, to generate the seed.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>
#include <pthread.h>
static bool HAS_URANDOM = true; // Global
unsigned int random_uint() {
unsigned int r_uint;
// Try to open the random generator device
FILE *f = fopen("/dev/urandom", "r");
if (f == NULL) {
if (HAS_URANDOM) {
// Warn that urandom isn't working, but fallthrough to rand()
printf("---- Failed loading random generator device /dev/urandom. Defaulting to rand().\n");
srand((unsigned int) time(NULL));
HAS_URANDOM = false;
}
r_uint = (unsigned int) rand();
} else {
// If we have urandom, just read from it and cast to uint
fread(&r_uint, sizeof(r_uint), 1, f);
fclose(f);
}
return r_uint;
}
// Inclusive range
// https://stackoverflow.com/a/17554531/2080712
unsigned int generate_uint(unsigned int lower, unsigned int upper) {
if (upper - lower == UINT_MAX) {
fprintf(stderr, "Invalid bounds on generate_int().\n");
exit(EXIT_FAILURE);
}
unsigned int r_uint;
const unsigned int range = 1 + (upper - lower);
if (range == 0) {
fprintf(stderr, "Invalid range!\n---- upper=%d\n---- lower=%d\n---- range=%d\n", upper, lower, range);
exit(EXIT_FAILURE);
}
const unsigned int buckets = UINT_MAX / range;
const unsigned int limit = buckets * range;
/* Create equal size buckets all in a row, then fire randomly towards
* the buckets until you land in one of them. All buckets are equally
* likely. If you land off the end of the line of buckets, try again. */
do {
r_uint = random_uint();
} while (r_uint >= limit);
unsigned int res = lower + (r_uint / buckets);
return res;
}
typedef struct {
pthread_mutex_t lock; // Our lock to avoid data races
long sum; // The sum value
} sum_t;
// Thread function
void *do_sum(void *arg) {
sum_t *sum = (sum_t*)(arg); // Reinterpret the argument as sum_t
int val = generate_uint(0, 100) - 100; // Generate an integer in the range we want
pthread_mutex_lock(&sum->lock); // Lock the value
sum->sum += val; // Sum
pthread_mutex_unlock(&sum->lock); // Unlock the value
return NULL;
}
int main(int argc, char *argv[]) {
// Guarantee argument
if(argc != 2) {
printf("Please provide a number of threads.\n");
exit(EXIT_FAILURE);
}
// Get our thread count
long count = strtol(argv[1], NULL, 10);
// Allocate threads
pthread_t threads[count];
// Create & initialize sum structure
sum_t sum;
pthread_mutex_init(&(sum.lock), NULL);
sum.sum = 0;
// Run sum threads
for (long i = 0; i < count; ++i) {
pthread_create(&(threads[i]), NULL, do_sum, &sum);
}
// Wait until they have finished
for (long i = 0; i < count; ++i) {
pthread_join(threads[i], NULL);
}
// Destroy the mutex lock
pthread_mutex_destroy(&(sum.lock));
// Print result
printf("%ld\n", sum.sum);
return 0;
}

Segmentation Fault in C producer/consumer using messagequeue

I am doing an assignment that implements the producer / consumer problem using a UNIX message queue as the data structure shared by a single producer and three consumers. The program I am creating is supposed to create a child process and the child process will in turn create three threads. The parent process is to be the producer and the three threads will be the consumers. The number of items, N, that are to be produced will be provided to the program via the command line. After spawning the child process the parent will enter an N-iteration loop. In each iteration of the loop the parent will do the following:
1) Generate a random number, R, in the range of 0-999.
2) Send a message containing R.
3) Add R to a running total of all values produced.
4) Display the string “Producer produced a R”.
5) Put the producer to sleep for 0-1 seconds using sleep(rand()%2).
After the N iterations have completed display the string "Total produced = XXXX” (where XXXX is the sum of all R values produced) and wait for the child to terminate. It is the parent’s responsibility to create and destroy the queue.
The child process will create three consumer threads, 0, 1 and 2. Each thread will enter an N/3 iteration loop. In each iteration of the loop each consumer thread will do the following:
1) Read a message containing a value, C, consumed from the queue.
2) Add C to a running total maintained by each consumer thread.
3) Display the string “Consumer thread Z consumed a C” where Z is the thread number – 0,1 or 2.
4) Put the consumer thread to sleep for 1-3 seconds using sleep((rand()%3)+1)
After N/3 iterations display the string "Total consumed by consumer thread Z = YYYY” where YYYY is the sum of all N/3 values consumed.I am receiving a segmentation fault in the last iteration of the loop and I am not sure why. Can anyone help me with this issue?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/sem.h>
#include <semaphore.h>
struct msgbuf {
long mtype;
int mnum;
};
int msqid;
unsigned long total;
pthread_mutex_t sem_id;
int init() {
srand (time(NULL));
msqid = msgget(IPC_PRIVATE, IPC_CREAT | 0600);
if (msqid == -1) { perror("msgget"); return EXIT_FAILURE; }
pthread_mutex_init(&sem_id, NULL);
total = 0;
return 0;
}
int producer() {
int R = rand() % 999;
struct msgbuf msg = {999, R};
if(msgsnd(msqid, &msg, sizeof(msg.mnum) + 1, 0) == -1) {
perror("msgsnd"); return -1; }
total += R;
return R;
}
void *consumer(int thread_num, int iteration) {
struct msgbuf msg;
int thread_total = 0;
while(iteration--) {
pthread_mutex_lock(&sem_id);
if (msgrcv(msqid, &msg, sizeof(msg.mnum) + 1, 0, 0) == -1)
perror("msgrcv");
thread_total += msg.mnum;
printf("Consumer thread %d consumed a %d\n", thread_num, msg.mnum);
pthread_mutex_unlock(&sem_id);
}
printf("Total consumed by consumer thread %d = %d\n", thread_num,
thread_total);
sleep((rand()%3)+1);
}
int main(int argc, char *argv[]) {
int N = argc > 1 ? atoi(argv[1]) : 10;
if (init() != 0) return EXIT_FAILURE;
for (int i=0;i<N;i++) {
int R = producer();
if(R == -1) return EXIT_FAILURE;
printf("Producer produced a %d\n", R);
sleep(rand()%2);
}
printf("Total produced = %lu\n", total);
pthread_t thread_nums[3];
for (int i=0; i<=4; i++) {
int iteration = i == 0 ? N/3 + (N%3) : N/3;
if(pthread_create(&thread_nums[i], NULL,
consumer(i, iteration), NULL) != 0) {
perror("pthread_create");
return EXIT_FAILURE;
}
}
for (int i=0;i<4;i++) pthread_join(thread_nums[i], NULL);
return 0;
}
Ok so in the main function, thread_nums has 3 "slots", where as the loop proceeding wants to go over 5 different "slots".
Also, the last loop accesses a "slot" which does not exist
Remember that an array of size [3] has only three positions. The last item is at index 2 (0,1,2), for a total of three elements.

Difficulty Creating Pthreads (Error 22)

Learning about pthreads, but I'm having trouble getting them created. Here is my output and the gdb information:
In main(), creating thread 1
ERROR: return code from pthread_create() is 22 for thread 1
In main(), creating thread 2
ERROR: return code from pthread_create() is 22 for thread 2
In main(), creating thread 3
ERROR: return code from pthread_create() is 22 for thread 3
In main(), creating thread 4
ERROR: return code from pthread_create() is 22 for thread 4
In main(), creating thread 5
ERROR: return code from pthread_create() is 22 for thread 5
Program received signal SIGSEGV, Segmentation fault. 0xb7fb4d8a in
pthread_join (threadid=76038327, thread_return=0x0)
at pthread_join.c:46 46 pthread_join.c: No such file or directory.
And here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#define SBUFSIZE 1025
char errorstr[SBUFSIZE];
FILE* inputfp[5];
void* f(void* inpFile) {
fprintf(stderr, "%s\n", (char*)inpFile);
return NULL;
}
int main (int argc, char* argv[]) {
int i;
/* Thread Variables */
pthread_attr_t attr;
pthread_t *th[argc-2]; //one thread for each input file
/* allocate memory for the threads */
for (i = 0; i < (argc-2); i++) {
th[i] = (pthread_t *) malloc(sizeof(pthread_t));
inputfp[i] = fopen(argv[i], "r");
if (!inputfp[i]) {
sprintf(errorstr, "Error Opening Input File: %s", argv[i]);
perror(errorstr);
}
}
/* Create one thread for each input file */
for (i = 1; i < (argc - 1); i++) {
fprintf (stderr, "In main(), creating thread %1d\n", i);
int rc = pthread_create (th[i], &attr, f, inputfp[i-1]);
if (rc) {
printf("ERROR: return code from pthread_create() is %d for thread %d\n",
rc, i);
}
}
/* wait for the threads to finish */
for (i = 1; i < (argc - 1); i++) {
pthread_join(*th[i], 0);
}
return EXIT_SUCCESS;
}
I'm missing something, but I don't know what. Can anyone help? Thank you!
EDIT: Here is how I changed the code per the suggestion from Joachim Pileborg. I'm still getting error 22 returning from pthread_create(), but the SIGSEGV error on pthread_join is no longer occurring.
Anyone have any suggestions about how I can get the pthread_create() to return 0 (indicating a successful thread creation)? Thanks again!
int main (int argc, char* argv[]) {
int i;
/* Thread Variables */
pthread_attr_t attr;
pthread_t *th[argc-2]; //one thread for each input file
/* allocate memory for the threads */
for (i = 0; i < (argc-2); i++) {
th[i] = (pthread_t *) malloc(sizeof(pthread_t));
printf("%s\n", argv[i+1]);
inputfp[i] = fopen(argv[i+1], "r");
if (!inputfp[i]) {
sprintf(errorstr, "Error Opening Input File: %s", argv[i]);
perror(errorstr);
}
}
/* Create one thread for each input file */
for (i = 0; i < (argc - 2); i++) {
fprintf (stderr, "In main(), creating thread %1d\n", i);
int rc = pthread_create (th[i], &attr, f, inputfp[i]);
if (rc) {
printf("ERROR: return code from pthread_create() is %d for thread %d\n",
rc, i);
}
}
/* wait for the threads to finish */
for (i = 0; i < (argc - 2); i++) {
pthread_join(*th[i], 0);
}
return EXIT_SUCCESS;
}
You have one loop where you loop from zero to argc - 3, and uses the correct indexes (zero to "size of array minus one".
Then you have two loops where you loop from one to argc - 2, and use indexes from one to "size of array".
You should use the same loop as the first one in all three places.

The thread created by pthread_create the same with the kernel thread?

I use the command below to view the maximum number of threads my system allows:
# cat /proc/sys/kernel/threads-max
And the number is 772432.
However, I use the code below to create 1 million threads. And it works.
#include <pthread.h>
#include <stdio.h>
static unsigned long long thread_nr = 0;
pthread_mutex_t mutex_;
void* inc_thread_nr(void* arg) {
/* int arr[1024][1024]; */
(void*)arg;
pthread_mutex_lock(&mutex_);
thread_nr ++;
pthread_mutex_unlock(&mutex_);
}
int main(int argc, char *argv[])
{
int err;
int cnt = 0;
pthread_mutex_init(&mutex_, NULL);
while (cnt < 1000000) {
pthread_t pid;
err = pthread_create(&pid, NULL, (void*)inc_thread_nr, NULL);
if (err != 0) {
break;
}
pthread_join(pid, NULL);
cnt++;
}
pthread_mutex_destroy(&mutex_);
printf("Maximum number of threads per process is = %d\n", thread_nr);
}
The output is :
Maximum number of threads per process is = 1000000
which is larger than the maximum number of threads. What is the reason for this? And is the thread create by pthread_create the same with the kernel thread?
My OS is Fedora 16, with 12 cores, 48G RAM.

Resources