1

I am trying to get 0 keys missing output when running my program with 2 threads. When i run it with 1 thread there are 0 keys missing but when i run my program with 2 threads, it has heaps of keys missing.

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include <pthread.h>
#include <sys/time.h>

#define NBUCKET 5
#define NKEYS 100000

struct entry {
  int key;
  int value;
  struct entry *next;
};
struct entry *table[NBUCKET];
int keys[NKEYS];
int nthread = 1;

pthread_mutex_t lock;

double
now()
{
 struct timeval tv;
 gettimeofday(&tv, 0);
 return tv.tv_sec + tv.tv_usec / 1000000.0;
}

static void 
insert(int key, int value, struct entry **p, struct entry *n)
{
  struct entry *e = malloc(sizeof(struct entry));
  e->key = key;
  e->value = value;
  e->next = n;
  *p = e;
}

static 
void put(int key, int value)
{
  int i = key % NBUCKET;

  // is the key already present?
  struct entry *e = 0;
  for (e = table[i]; e != 0; e = e->next) {
    if (e->key == key)
      break;
  }
  if(e){
    // update the existing key.
    e->value = value;
  } else {
    // the new is new.
    insert(key, value, &table[i], table[i]);

  }
}

static struct entry*
get(int key)
{
  int i = key % NBUCKET;


  struct entry *e = 0;
  for (e = table[i]; e != 0; e = e->next) {
    if (e->key == key) break;
  }

  pthread_mutex_t lock;
  pthread_mutex_init(&lock, NULL);
  pthread_mutex_lock(&lock);
  pthread_mutex_unlock(&lock);

  return e;
}

static void *
put_thread(void *xa)
{
  int n = (int) (long) xa; // thread number
  int b = NKEYS/nthread;

  for (int i = 0; i < b; i++) {
    put(keys[b*n + i], n);
  }
  
  pthread_mutex_t lock;
  pthread_mutex_init(&lock, NULL);
  pthread_mutex_lock(&lock);
  pthread_mutex_unlock(&lock);

  return NULL;
}

static void *
get_thread(void *xa)
{
  int n = (int) (long) xa; // thread number
  int missing = 0;

  for (int i = 0; i < NKEYS; i++) {
    struct entry *e = get(keys[i]);
    if (e == 0) missing++;
  }

  pthread_mutex_t lock;
  pthread_mutex_init(&lock, NULL);
  pthread_mutex_lock(&lock);
  pthread_mutex_unlock(&lock);
   
  printf("%d: %d keys missing\n", n, missing);
  return NULL;
}

int
main(int argc, char *argv[])
{
  pthread_t *tha;
  void *value;
  double t1, t0;


  if (argc < 2) {
    fprintf(stderr, "Usage: %s nthreads\n", argv[0]);
    exit(-1);
  }
  nthread = atoi(argv[1]);
  tha = malloc(sizeof(pthread_t) * nthread);
  srandom(0);
  assert(NKEYS % nthread == 0);
  for (int i = 0; i < NKEYS; i++) {
    keys[i] = random();
  }

  //
  // first the puts
  //
  t0 = now();
  for(int i = 0; i < nthread; i++) {
    assert(pthread_create(&tha[i], NULL, put_thread, (void *) (long) i) == 0);
  }
  for(int i = 0; i < nthread; i++) {
    assert(pthread_join(tha[i], &value) == 0);
  }
  t1 = now();

  printf("%d puts, %.3f seconds, %.0f puts/second\n",
         NKEYS, t1 - t0, NKEYS / (t1 - t0));

  //
  // now the gets
  //
  t0 = now();
  for(int i = 0; i < nthread; i++) {
    assert(pthread_create(&tha[i], NULL, get_thread, (void *) (long) i) == 0);
  }
  for(int i = 0; i < nthread; i++) {
    assert(pthread_join(tha[i], &value) == 0);
  }
  t1 = now();

  printf("%d gets, %.3f seconds, %.0f gets/second\n",
         NKEYS*nthread, t1 - t0, (NKEYS*nthread) / (t1 - t0));
}

I have implemented the pthread mutex locks and unlocks in the put_thread() and the get_thread function. Although when i compile that code on linux (ubuntu), it gives me the following error:

usr/bin/ld: /tmp/ccfYHgsz.o: in function `main': 
thr.c:(.text+@x4f0): undefined reference to `pthread_create'
usr/bin/ld: thr.c:(.text+0x551): undefined reference to `pthread_join'
usr/bin/ld: thr.c:(.text+0x620): undefined reference to `pthread_create'
usr/bin/ld: thr.c:(.text+0x681): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status

Would really appreciate if i could get some help on this, Thanks!

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • you need to link with the pthread library using `-pthread`, more info [here](https://stackoverflow.com/questions/1662909/undefined-reference-to-pthread-create-in-linux) – yano Jun 13 '22 at 15:00
  • 2
    Please don't put images of text into your question, copy'n'paste the text inline. That allow people to (Hint!) search for the error message. That said, looking at the code, there is zero documentation which data structures are shared between threads and which mutex is used to protect which data. Add that, because writing it down forces you to structure your code and it allows you to look at some access and determine whether it is correct or not in a multithreaded context. Lastly, you're getting a compile error, so go and extract a [mcve] and include that, not the whole code you put here. – Ulrich Eckhardt Jun 13 '22 at 17:21
  • You seem to have asked two entirely separate questions. The link errors presented at the end will have prevented a (new) executable from being created. If you successfully ran a multithreaded version of your program, then it was not one with which those errors were associated. – John Bollinger Jun 14 '22 at 20:38
  • You have several functions each creating locking, and immediately unlocking *their own* mutexes. Mutexes don't do any good unless the various threads involved all use the same one(s). They also offer very little advantage to operations performed in regions where the mutex is not held locked. – John Bollinger Jun 15 '22 at 16:01

0 Answers0