C线程同步

C线程同步,c,linux,multithreading,C,Linux,Multithreading,我有一个问题,使用多个线程和同步他们在一个适当的顺序。问题的状态如下:我有44个线程从1-44。我可以有最多4个线程,可以进入关键领域的时刻。只有当关键区域中有4条螺纹(包括它们)时,12号螺纹才必须关闭。问题如下:有时线程关闭得很好,有时关闭得不好。我不知道它什么时候会来,它可能是最后一个,所以我强迫它成为第一个进入关键区域的。这是同步44个线程的代码示例: void *thread_sync_P7(void *arg){ int *val = (int*)arg; if(*

我有一个问题,使用多个线程和同步他们在一个适当的顺序。问题的状态如下:我有44个线程从1-44。我可以有最多4个线程,可以进入关键领域的时刻。只有当关键区域中有4条螺纹(包括它们)时,12号螺纹才必须关闭。问题如下:有时线程关闭得很好,有时关闭得不好。我不知道它什么时候会来,它可能是最后一个,所以我强迫它成为第一个进入关键区域的。这是同步44个线程的代码示例:

void *thread_sync_P7(void *arg){
    int *val = (int*)arg;

    if(*val != 12) {
        sem_wait(&semP7_2);
    }

    sem_wait(&semP7_1);
    info(BEGIN, 7, *val);

    if(*val == 12) {
        sem = 0;
        for(int i = 0;i < threadP7 - 1;i++){
            sem_post(&semP7_2);
        }
    }


    info(END, 7, *val);
    sem_post(&semP7_1);

    return NULL;   
}

如您所见,P7T12是id为12的线程。它后面是T2和T3,但是它关闭了,并且只显示了3个线程。如何更好地同步它们?

有几种方法可以实现这一点:

  • (等待)使用与最终条件关联的条件变量。您的12号线程将等待该条件为真,其他线程将评估该条件并在该条件为真时唤醒它。当每个线程进入临界区域时,它会评估条件,如果为true,则唤醒线程。当每个线程离开临界区域时,重新评估条件(这意味着用临界区域中的线程数增加/减少一个变量),当线程12被唤醒时,它可以关闭(关闭意味着你想要什么),在这种情况下,你的线程正在等待条件发生关闭

  • (轮询)如果您的线程在决定是否关闭之前有事情要做,只需在进入关键区域时评估其他线程上的条件并存储它(您需要在第一个线程上嵌套一个关键区域即可)。您还可以有一个布尔变量,指示过去是否达到了条件(我们已经达到了内部的四个线程,即使现在没有这四个线程),然后,您的线程可以自由地执行另一个任务,并且只有在必须在特定时间点关闭时才进行计算

  • (已发出信号)如果您必须异步向进程发出信号,使其离开并关闭,只需向其发送一个信号即可。这将中断线程执行,您可以决定中止任务或在信号处理程序上发出信号后继续。请注意,处理信号(向进程发送信号,通常是一组线程)并将其附加到进程的特定线程是很难正确实现的,您必须确定哪些线程将处理哪种类型的信号,这是一件复杂的事情


  • 一个线程“关闭”意味着什么?要达到函数的结尾,请像我在那里展示的那样显示日志并返回NULL。如果您尝试按顺序执行多个线程,那么编程多个线程有什么意义?
    [T] BEGIN P7 T12 pid=24850 ppid=24848 tid=825038592
    
    [T]  END  P4 T3 pid=24848 ppid=24846 tid=900572928
    
    [T] BEGIN P7 T2 pid=24850 ppid=24848 tid=908965632
    
    [T]  END  P4 T1 pid=24848 ppid=24846 tid=917358336
    
    [T] BEGIN P7 T3 pid=24850 ppid=24848 tid=900572928
    
    [T]  END  P5 T0 pid=24851 ppid=24847 tid=925882176
    
    [T]  END  P7 T12 pid=24850 ppid=24848 tid=825038592
    
    [T] BEGIN P7 T4 pid=24850 ppid=24848 tid=892180224