如何在读写器多线程程序中设置回调

时间:2016-01-22 22:57:36

标签: c multithreading callback pthreads

我编写了一个读/写锁实现,我打算做的是为每个线程设置回调。假设我们有3个读取器线程,其中3个读取了值X.现在,写入器线程将值X更新为X + 100。这应该发送一个回调给所有3个读取器线程的值已更改。我们如何在C编程语言的多线程环境中实现这样的回调?

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdint.h>

sem_t dbAccess;
sem_t readCountAccess;

int readCount=0;

void *Reader(void *arg);
void *Writer(void *arg);

int main(int argc, char* argv[])
{
  int i=0, num_of_readers = 0, num_of_writers = 0;

  //inititalizing semaphores                                                                                                                                                                                
  sem_init(&readCountAccess,0,1);
  sem_init(&dbAccess,0,1);

  pthread_t readers_tid[100], writer_tid[100];
  num_of_readers = atoi(argv[1]);
  num_of_writers = atoi(argv[2]);

  for(i = 0; i < num_of_readers; i++)
    {
      pthread_create(&readers_tid[i], NULL , Reader, (void *) (intptr_t) i);
    }

  for(i = 0;i < num_of_writers; i++)
    {
      pthread_create(&writer_tid[i], NULL, Writer, (void *) (intptr_t) i);
    }

  for(i = 0; i < num_of_writers; i++)
    {
      pthread_join(writer_tid[i],NULL);
    }

  for(i = 0; i < num_of_readers; i++)
    {
      pthread_join(readers_tid[i], NULL);
    }

  sem_destroy(&dbAccess);
  sem_destroy(&readCountAccess);
  return 0;
}

void * Writer(void *arg)
{

  sleep(1);
  int temp=(intptr_t) arg;
  printf("Writer %d is trying to enter into database for modifying the data\n",temp);
  sem_wait(&dbAccess);
  printf("Writer %d is writting into the database\n",temp);
  printf("Writer %d is leaving the database\n");
  sem_post(&dbAccess);
}

void *Reader(void *arg)
{
  sleep(1);
  int temp=(intptr_t) arg;
  printf("Reader %d is trying to enter into the Database for reading the data\n",temp);
  sem_wait(&readCountAccess);
  readCount++;
  if(readCount==1)
    {
      sem_wait(&dbAccess);
      printf("Reader %d is reading the database\n",temp);
    }
  sem_post(&readCountAccess);
  sem_wait(&readCountAccess);
  readCount--;
  if(readCount==0)
    {
      printf("Reader %d is leaving the database\n",temp);
      sem_post(&dbAccess);
    }
  sem_post(&readCountAccess);
}

1 个答案:

答案 0 :(得分:0)

我可以看到两种可能的方法:
1.当读者想要得到通知时,让他们调用一个函数。作者必须在每个读者线程上标记一些内容,表示他们必须在共享变量上调用您的CB。这将是我的首选方法,因为我设计读者知道他们何时需要这些更新 2.通知读者让他们从信号处理程序执行一些代码。您可以使用SIG_USR1 / 2,并在某处添加一些额外的标记,以了解更改的内容和调用的内容。显然,这不太干净,但是当第三方创建这些线程并且你无法控制他们正在做的事情时,我认为会更方便。

HTH

修改

我忘了另一个重要的事情 - 如果你只是更新POD变量(int等),你可以使用方法1和seqlock以及每个读者线程的本地副本。这样每个读者都会知道价值的变化。

另一个考虑因素是,您是否需要读者只知道最后一个值,或者他们是否需要响应每一个变化?如果你需要响应每一个更改,你可以使用一个无锁的队列,每个读者一个,并让作者进入每一个。