2017-11-11 74 views
0

我正在使用pthreads库来尝试使用显示器实现读写器应用程序。带显示器的读写器

我打电话给我的线程函数的主要方式如下

pthread_t *tid; 
tid = (pthread_t*)malloc(sizeof(pthread_t)*(r + w)); 
int addr = 0; 
//Create r # readers 
for (int a = 0; a < r; a++) 
{ 
    pthread_create(&tid[addr], NULL, Reader, (void*)&a); 
    addr++; 
} 

,然后他们通过以下3个功能完成它们的功能调用

void *Reader(void *pid) 
{ 
    static int *id = (int*)pid; 
    for (int i = 0; i < 10; i++) 
    { 
     beginRead(id); 
     endRead(); 
     #ifdef __unix 
      usleep(R); 
     #endif 
     #ifdef _WIN32 
      Sleep(R); 
     #endif 
    } 
    return 0; 
} 

void beginRead(int *id) 
{ 
    //If writelock or writer_queued then wait(canRead) 
    pthread_mutex_lock(&writelock); 
    while (writer_queued) 
    { 
     reader_queued = true; 
     pthread_cond_wait(&canRead, &writelock); 
     reader_queued = false; 
    } 
    readers++; 
    pthread_mutex_unlock(&writelock); 
    pthread_mutex_lock(&output); 
    time_t t = time(0); 
    struct tm * now = localtime(&t); 
    fprintf(outputfile, "DB value read =:%d:%d by reader number: %d\n", now-  >tm_sec, (now->tm_sec)/1000, (int)*id); 
    printf("DB value read =:%d:%d by reader number: %d\n", now->tm_sec, (now->tm_sec)/1000, (int)*id); 
    pthread_mutex_unlock(&output); 
    pthread_cond_broadcast(&canRead); 
} 

void endRead() 
{ 
    --readers; // just finished a reader 
    if (readers == 0) 
    { 
     pthread_cond_signal(&canWrite); 
    } 
} 

据说这是为了使每一个线程进入代码的关键部分10次(所以如果创建了2个线程,它将访问关键部分20次)我得到线程访问我的代码的关键部分正确的次数,我只是无法得到它打印正确的线程ID#

所以,如果我调用此函数r = 2和R = 200我的输出将是:

DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 

当它应该是沿

DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number:1 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 
DB value read =:30:0 by reader number: 2 

取决于定时线的东西每个线程访问临界区域

+0

读卡器后面是2打开和3关闭。 'endRead'有2个打开和1个关闭。 – user4581301

+0

代码将***地址***('a'的地址)传递给每个***线程。 – alk

+0

OT:没有必要在C中投射'void'-Pointers – alk

回答

0

代码通过相同的地址(地址a)至线程。

你想传递一个单独的地址给每个线程。

比如,你可以这样做:

struct thread_info 
{ 
    pthread_t tid; 
    int id; 
} 

... 

    struct thread_info * pti = malloc((r + w) * sizeof *pit); 
    size_t addr = 0; 

    //Create r # readers 
    for (int a = 0; a < r; a++) 
    { 
    pti[addr]->id = a; 
    pthread_create(&pti[addr]->tid, NULL, Reader, &pti[addr]->id); 

    addr++; 
    } 

而且这条线

--readers; // just finished a reader 

同时访问readers保护。