2

在下面的代码中,我创建了一个具有循环的线程,当我调用条件时将执行完整的迭代。但是,如果我调用它 1000 次,则该值invoking_thread不同于exec_thread. main发生了什么,我该如何解决这个问题?我不想退出正在运行的线程threadfunc,因为我可能需要将它用于进一步的操作。

#include < pthread.h> 
#include < stdio.h>

pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
int invoking_thread = 0, exec_thread = 0; 
pthread_t pth; 

void *threadfunc(void *parm) 
{ 
    int x; 
    for (;;) { 
        pthread_mutex_lock(&mutex); 
        pthread_cond_wait(&cond, &mutex); 
        //printf("Inside the thread %d\n", ins); 
        exec_thread++; 
        pthread_mutex_unlock(&mutex); 
    } 
    return NULL; 
} 


void create_thread () { 
    pthread_create(&pth,NULL,threadfunc,"foo"); 
} 

int main(int argc, char **argv) 
{ 
    create_thread(); 
    int y = 0; 
    while (1) { 
        if (y == 1000) { 
            break; 
        } 
        y++; 
        invoking_thread++; 
        printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread); 
        pthread_cond_signal( &cond ); 
        pthread_mutex_lock( &mutex ); 
        pthread_mutex_unlock( &mutex ); 
    } 
    printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread); 
    printf("Main completed\n"); 
    return 0; 
} 

进一步解释的细节:我可以告诉你我的整个情况:一个 1000 大小的数组被初始化为 0 值。1 个线程以无限循环启动。对于 1000 次迭代,我将信号传递给线程以增加数组中每个元素的值。传递信号后,这些值在循环中乘以 2。在下一步中,再次将 1000 个信号传递给线程以递增数组中每个元素的值。然后,与之前一样,所有元素值在循环中乘以 2。然后打印结果。

现在,添加一些块,大多数时候我都会遇到分段错误。其余时间我没有得到想要的价值。

  #include < pthread.h>

  #include < stdio.h>

   pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

   pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

   int invoking_thread = 0, exec_thread = 0, signal_count = 0;

   pthread_t pth;

   int res[1000];

 void *threadfunc(void *parm) { 

for (;;) { 

    pthread_mutex_lock(&mutex); 

    while (signal_count == 0)
        pthread_cond_wait(&cond, &mutex); 

    signal_count--; // consume a signal

//printf("Inside the thread res[%d]++\n", exec_thread);

    exec_thread++; 

res[exec_thread]++;

    pthread_mutex_unlock(&mutex); 

  }

  return NULL; 

  }


  void create_thread () {

      pthread_create(&pth,NULL,threadfunc,"foo");

  }


  int main(int argc, char **argv)
  {

create_thread();

int y;

for (y = 0;y<1000;y++) {
    res[y] = 0;
}
y = 0;
while (1) {
    if (y == 1000) {
        break;
    }
    y++;
    invoking_thread++;
    //printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread);
    pthread_mutex_lock( &mutex ); 
        signal_count++;
        pthread_mutex_unlock( &mutex ); 
        pthread_cond_signal( &cond ); 
}
printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread);

for (y = 0;y<1000;y++) {
    res[y] = res[y]*2;
}
exec_thread = 0;
y = 0;
while (1) {
    if (y == 1000) {
        break;
    }
    y++;
    invoking_thread++;
    //printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread);
    pthread_mutex_lock( &mutex ); 
        signal_count++;
        pthread_mutex_unlock( &mutex ); 
        pthread_cond_signal( &cond ); 
}
printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread);

for (y = 0;y<1000;y++) {
    res[y] = res[y]*2;
}

// result
for (y = 0;y<1000;y++) {
    printf("%d result for %d\n",res[y], y);
}

printf("Main completed\n");
return 0;
  } 

因此我的问题是,线程调用应该在前 1000 个信号之后等待,它没有等待,然后让代码进行计算,然后应该允许它再进行 1000 次调用。依此类推以获得所需的结果。希望我能够解释我的情况。

4

3 回答 3

2

如果有线程等待,pthread_cond_signal()它将唤醒任何等待条件的线程。如果没有,那么该调用将无济于事。这很可能是您的情况。有几个后续调用,而工作线程实际上并没有休眠。pthread_cond_signal()

为了确保一个调用一工作人员通过,您将必须使用两个pthread_cond_t- 一个来表示工作人员的启动,第二个用于通知工作已经结束。另一个是忙着等到 1000 个工作完成。这是修改后的代码:

int main(int argc, char **argv)
{
    create_thread();
    int y = 0;
    int executed = 0;
    while (executed <1000) {
        invoking_thread++;
        printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread);
        pthread_mutex_lock( &mutex );
        executed = exec_thread; // read inside mutex to ensure variable visibility
        pthread_cond_signal( &cond );
        pthread_mutex_unlock( &mutex );
    }
    printf("Count: Invoked %d and Inside : %d\n", invoking_thread, exec_thread);
    printf("Main completed\n");
    return 0;
}
于 2013-08-20T08:39:03.570 回答
1

条件变量是无状态的。您期望条件变量具有“信号”状态。它不是。如果要将状态与条件变量相关联,则必须这样做。您可以有一个“signal_count”变量,然后执行以下操作:

void *threadfunc(void *parm) 
{ 
    int x; 
    for (;;) { 
        pthread_mutex_lock(&mutex); 
        while (signal_count == 0)
            pthread_cond_wait(&cond, &mutex); 
        signal_count--; // consume a signal
        //printf("Inside the thread %d\n", ins); 
        exec_thread++; 
        pthread_mutex_unlock(&mutex); 
    } 
    return NULL; 
}

相似地:

    pthread_mutex_lock( &mutex ); 
    signal_count++;
    pthread_mutex_unlock( &mutex ); 
    pthread_cond_signal( &cond ); 

请注意,互斥锁保护状态,您必须实现状态,除非您知道需要等待,否则不得调用,并且在返回pthread_cond_wait时不得假设状态具有任何特定值。pthread_cond_wait这就是您使用条件变量的方式。

于 2013-08-20T08:44:44.193 回答
0

您是否忘记添加pthread_join()main 以等待所有线程完成计算?

[看这里]

于 2013-08-20T08:30:14.580 回答