简体   繁体   English

使用互斥锁在2个进程之间进行屏障同步

[英]Barrier Synchronization between 2 process using mutex

I need to implement barrier synchronization between 2 threads using mutex (only). 我需要使用互斥锁(仅)在2个线程之间实现屏障同步。 Barrier synchronization is that 2 threads will wait for each other to meet at predefined step before proceeding. 屏障同步是2个线程将在预定义的步骤互相等待,然后再继续。

I am able to do it using seamaphore but how can I achieve this only using mutex . 我能够使用seamaphore做到这一点,但是我如何仅使用互斥锁来实现这一点 I was given a hint that I need 2 mutex not 1 to do this. 提示我需要2个互斥锁而不是1个。

Using Seamaphore: 使用Seamaphore:

#include <pthread.h>
#include <semaphore.h>
using namespace std;

sem_t s1;
sem_t s2;


void* fun1(void* i)
{
    cout << "fun1 stage 1" << endl;
    cout << "fun1 stage 2" << endl;
    cout << "fun1 stage 3" << endl;
    sem_post (&s1);
    sem_wait (&s2);
    cout << "fun1 stage 4" << endl;
}

void* fun2(void* i)
{
    cout << "fun2 stage 1" << endl;
    cout << "fun2 stage 2" << endl;
//    sleep(5);
    sem_post (&s2);
    sem_wait (&s1);
    cout << "fun2 stage 3" << endl;
}

main()
{
    sem_init(&s1, 0, 0);
    sem_init(&s2, 0, 0);
    int value; 
    sem_getvalue(&s2, &value);
    cout << "s2 = " << value << endl;

    pthread_t iThreadId;

    cout << pthread_create(&iThreadId, NULL, &fun2, NULL) << endl;
//    cout << pthread_create(&iThreadId, NULL, &fun2, NULL) << endl;
    pthread_create(&iThreadId, NULL, &fun1, NULL);
    sleep(10);
}

Compile the above code as "g++ barrier.cc -lpthread" 将以上代码编译为“ g ++ barrier.cc -lpthread”

How about NO MUTEXES and no locks? 没有杂物和锁怎么办? Using ATOMIC OPERATIONS only: 仅使用原子操作

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

static sigset_t _fSigSet;
static volatile int _cMax=20, _cWait = 0;
static pthread_t    _aThread[1000];

void * thread(void *idIn)
{
int nSig, iThread, cWait, id = (int)idIn;

    printf("Start %d\n", id, cWait, _cMax);
    // do some fake weork
    nanosleep(&(struct timespec){0, 500000000}, NULL);
    // barrier
    cWait = __sync_add_and_fetch(&_cWait, 1);
    printf("Middle %d, %d/%d Waiting\n", id, cWait, _cMax);
    if (cWait < _cMax)
    {        
        // if we are not the last thread, sleep on signal
        sigwait(&_fSigSet, &nSig); // sleepytime
    }
    else
    {
        // if we are the last thread, don't sleep and wake everyone else up
        for (iThread = 0; iThread < _cMax; ++iThread)
            if (iThread != id)
                pthread_kill(_aThread[iThread], SIGUSR1);
    }

    // watch em wake up    
    cWait = __sync_add_and_fetch(&_cWait, -1);
    printf("End %d, %d/%d Active\n", id, cWait, _cMax);

    return 0;
}

int main(int argc, char** argv)
{
    pthread_attr_t attr;
    int i, err;

    sigemptyset(&_fSigSet);
    sigaddset(&_fSigSet, SIGUSR1);
    sigaddset(&_fSigSet, SIGSEGV);

    printf("Start\n");
    pthread_attr_init(&attr);
    if ((err = pthread_attr_setstacksize(&attr, 16384)) != 0)
    {
        printf("pthread_attr_setstacksize failed: err: %d %s\n", err, strerror(err));
        exit(0);
    }

    for (i = 0; i < _cMax; i++)
    {
        if ((err = pthread_create(&_aThread[i], &attr, thread, (void*)i)) != 0)
        {
            printf("pthread_create failed on thread %d, error code: %d %s\n", i, err, strerror(err));
            exit(0);
        }
    }

    for (i = 0; i < _cMax; ++i)
        pthread_join(_aThread[i], NULL);

    printf("\nDone.\n");
    return 0;
}

I am not sure that you need two mutexes, with one mutex and a condition variable and an extra flag might be enough. 我不确定您是否需要两个互斥锁,其中一个互斥锁和一个条件变量以及一个额外的标志可能就足够了。 The idea is that you enter the critical section by acquiring the mutex, then you check whether you are the first thread to come, if so, you wait on the condition. 这个想法是您通过获取互斥锁进入关键部分,然后检查是否是第一个线程,如果是,则等待条件。 If you are the second thread coming then you wake up the waiting thread and both leave. 如果您是第二个线程,那么您将唤醒等待的线程,并且两个线程都将离开。

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

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