我编写了一个读/写锁实现,我打算做的是为每个线程设置回调。假设我们有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);
}
答案 0 :(得分:0)
我可以看到两种可能的方法:
1.当读者想要得到通知时,让他们调用一个函数。作者必须在每个读者线程上标记一些内容,表示他们必须在共享变量上调用您的CB。这将是我的首选方法,因为我设计读者知道他们何时需要这些更新
2.通知读者让他们从信号处理程序执行一些代码。您可以使用SIG_USR1 / 2,并在某处添加一些额外的标记,以了解更改的内容和调用的内容。显然,这不太干净,但是当第三方创建这些线程并且你无法控制他们正在做的事情时,我认为会更方便。
HTH
修改强>
我忘了另一个重要的事情 - 如果你只是更新POD变量(int等),你可以使用方法1和seqlock以及每个读者线程的本地副本。这样每个读者都会知道价值的变化。
另一个考虑因素是,您是否需要读者只知道最后一个值,或者他们是否需要响应每一个变化?如果你需要响应每一个更改,你可以使用一个无锁的队列,每个读者一个,并让作者进入每一个。