简体   繁体   English

使用pthread_join的pthread的同步问题

[英]Synchronization problem with pthreads using pthread_join

I have the following loops , 我有以下循环,

for (i = 1; i < nDiag; ++i)
{
    elem = findelemnum();
    taskarr[3]= elem;
    if(threadnum > elem) limit = elem;
    else limit=threadnum;

    if (i <= lenA) 
    {
        si = i;
        sj = 1;
    } 
    else 
    {
        si = lenA;
        sj = i - lenA + 1;
    }
    taskarr[0] = si, taskarr[1] = sj;  

    for (j = 0; j < limit; ++j) 
    {
        taskarr[2] = j;
        wakeup = 0;
        pthread_create(&threads[j], NULL, mytask, taskarr);
        while(!wakeup){
        }
    }
    for (int j=0; j < limit ;j++){
        pthread_join(threads[j],NULL);  
    } 
}

I want to synchronize my threads so that all threads have finished the inner loop first and then a new loop (i++) will start. 我想同步我的线程,以便所有线程都先完成内部循环,然后再开始一个新的循环(i ++)。 For that reason I used the pthread_join function. 因此,我使用了pthread_join函数。 Though a new for i loop starts before its previous ends. 虽然有一个新的for i循环在其先前的结尾之前开始。 What I'm doing wrong? 我做错了什么?

If you want to wait for a specific condition to happen use the class of functions pthread_cond_* . 如果要等待特定情况发生,请使用函数类pthread_cond_*

If you just want to wait for the thread to do their stuff remove while(!wakeup){} . 如果只想等待线程执行操作,则删除while(!wakeup){} This works because 这行得通,因为

int pthread_join(pthread_t thread, void **value_ptr); int pthread_join(pthread_t线程,void ** value_ptr);

The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated. pthread_join()函数会暂停调用线程的执行,直到目标线程终止为止,除非目标线程已经终止。

So in the following snippet you first create limit threads and they start running right away. 因此,在以下代码段中,您首先创建了限制线程,它们立即开始运行。 Then you wait for every thread to end, that is you suspend the calling thread until the termination of limit threads. 然后,您等待每个线程结束,即暂停调用线程,直到限制线程终止。

for (j = 0; j < limit; ++j) 
{
    taskarr[2] = j;
    wakeup = 0;
    pthread_create(&threads[j], NULL, mytask, taskarr);
}

for (int j=0; j < limit ;j++){
    pthread_join(threads[j],NULL);  
} 

This is a little demo 这是一个小演示

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

#define NTHREAD 4
#define ITERATIONS 5

typedef struct _pcontext
{
    int id;
    int iteration;
}pcontext_t;

void* work(void* arg)
{
    pcontext_t* ctx = (pcontext_t*)arg;

    sleep(2); 

    printf("Thread ID: %d\n", ctx->id);
    printf("Iteration nr: %d\n", ctx->iteration);
    printf("Done.\n\n");

    return NULL;
}

int main()
{
    pthread_t thread[NTHREAD];
    pcontext_t ctx[NTHREAD];
    int err;
    int i,j;

    for(j = 0; j < ITERATIONS; j++)
    {
        for(i = 0; i < NTHREAD; i++)
        {
            ctx[i].id = i;
            ctx[i].iteration = j;
            err = pthread_create(&thread[i], NULL, work, (void*)(&(ctx[i])));
            if (err)
            {
                printf("An error occured: %d", err);
                return err;
            }
        }

        printf("Waiting for the threads to end...\n");

        for(i = 0; i < NTHREAD; i++)
        {
          pthread_join(thread[i], (void**)NULL);    
        }

        printf("Threads ended.\n");
        printf("Iteration %d ended.\n\n", j);
    } 

    return 0;
}

Output: 输出:

gcc -Wall -Wextra -pedantic -pthread -o main main.c 
Waiting for the threads to end...
Thread ID: 1
Iteration nr: 0
Done.

Thread ID: 0
Iteration nr: 0
Done.

Thread ID: 2
Iteration nr: 0
Done.

Thread ID: 3
Iteration nr: 0
Done.

Threads ended.
Iteration 0 ended.

Waiting for the threads to end...
Thread ID: 0
Iteration nr: 1
Done.

Thread ID: 3
Iteration nr: 1
Done.

Thread ID: 2
Iteration nr: 1
Done.

Thread ID: 1
Iteration nr: 1
Done.

Threads ended.
Iteration 1 ended.

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

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