简体   繁体   English

为什么在C程序中调用线程数多于执行线程数?

[英]why invoking thread count is more than execution of thread count in C program?

In the code below, I create a thread having a loop which will perform a full iteration when I invoke the condition. 在下面的代码中,我创建了一个具有循环的线程,当我调用条件时,该循环将执行完整的迭代。 However, if i am invoking it 1000 times, the invoking_thread value is different than exec_thread at the end of main . 但是,如果我调用它的1000倍,在invoking_thread值比不同exec_thread在年底main What is happening, and how can I fix this issue? 发生了什么事,如何解决此问题? I do not want to exit the thread running threadfunc , because I may need to use it for further operations. 我不想退出运行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; 
} 

DETAILS of Further Explanation: I can tell you my whole situation: An array of 1000 size is initialized with 0 value. 详细说明:我可以告诉您我的整体情况:数组1000的大小用0值初始化。 1 thread is started with infinite loop. 1个线程以无限循环启动。 for 1000 iterations i pass the signal to thread to increment the value of each element of an array. 对于1000次迭代,我将信号传递给线程以增加数组中每个元素的值。 After passing signal, these values are multiplied by 2 in a loop. 传递信号后,这些值将在循环中乘以2。 In next step, again 1000 signals are passed to thread to increment the value of each element of an array. 在下一步中,再次将1000个信号传递给线程以增加数组中每个元素的值。 Then, same as previously, all the element values are multiplied by 2 in a loop. 然后,与之前相同,将所有元素值循环乘以2。 Then result is printed. 然后打印结果。

Now, adding some chunks, most of the time i am getting segmentation fault. 现在,添加一些块,大多数时候我都遇到了分段错误。 and rest of the time i am not getting desired value. 和其余的时间我没有得到期望的价值。

  #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;
  } 

Hence my question is, thread invocation should have to wait after first 1000 signals, which it is not waiting and then let the code do the calculations and then it should be allowed to do the further 1000 invocations. 因此,我的问题是,线程调用应该必须在前1000个信号之后等待,这不是等待,然后让代码进行计算,然后应该允许它再执行1000个调用。 and so on to get the desired result. 等等以获得理想的结果。 Hope i am able to explain my situation. 希望我能解释我的情况。

The pthread_cond_signal() will wake any thread waiting on the condition if there is a thread waiting. 如果有线程在等待,则pthread_cond_signal()将唤醒所有等待该条件的线程。 If not, then that call will do nothing. 如果没有,那么该呼叫将无济于事。 This is most probably what happens in your case. 这很可能是您遇到的情况。 There are several subsequent calls to pthread_cond_signal() , while the worker thread is not actually sleeping. 随后有多个对pthread_cond_signal()调用,而工作线程实际上并未处于睡眠状态。

To ensure one invoke-one worker pass you will have to use two pthread_cond_t - one to signal starting of worker, second for notifying that the work has ended. 为了确保一次调用一个工作程序传递,您将必须使用两个pthread_cond_t一个信号通知工作程序开始,第二个用于通知工作已结束。 Another is to busy wait until 1000 jobs have been done. 另一种是忙于等待1000个作业完成。 Here's a modified code: 这是修改后的代码:

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;
}

Condition variables are stateless. 条件变量是无状态的。 You are expecting the condition variable to have a "signaled" state. 您期望条件变量具有“信号”状态。 It does not. 它不是。 If you want to associate state with the condition variable, you must do so. 如果要将状态与条件变量关联,则必须这样做。 You can have a "signal_count" variable and then do this: 您可以具有“ 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; 
}

Similarly: 同理:

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

Notice that the mutex protects the state, you must implement the state, you must not call pthread_cond_wait unless you know you need to wait, and you must not assume the state has any particular value when pthread_cond_wait returns. 请注意,互斥锁保护状态,您必须实现状态,除非知道需要等待,否则不得调用pthread_cond_wait ,并且在pthread_cond_wait返回时,不得假定状态具有任何特定值。 That is how you use a condition variable. 这就是您使用条件变量的方式。

Are you forgetting to add pthread_join() in the main to wait until all threads are finished calculating? 您是否忘记在主线程中添加pthread_join()以等待所有线程完成计算?

[See here] [看这里]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM