Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用互斥锁在2个进程之间进行屏障同步_C++_Multithreading_Mutex - Fatal编程技术网

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

C++ 使用互斥锁在2个进程之间进行屏障同步,c++,multithreading,mutex,C++,Multithreading,Mutex,我需要使用互斥锁(仅限)在两个线程之间实现屏障同步。屏障同步是指两个线程在继续之前将等待彼此在预定义的步骤中相遇 我可以使用seamaphore来实现这一点,但是只有使用互斥锁才能实现这一点。我得到了一个提示,我需要2个互斥,而不是1来完成这项工作 使用Seamaphore: #include <pthread.h> #include <semaphore.h> using namespace std; sem_t s1; sem_t s2; void* fun1(

我需要使用互斥锁(仅限)在两个线程之间实现屏障同步。屏障同步是指两个线程在继续之前将等待彼此在预定义的步骤中相遇

我可以使用seamaphore来实现这一点,但是只有使用互斥锁才能实现这一点。我得到了一个提示,我需要2个互斥,而不是1来完成这项工作

使用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);
}
#包括
#包括
使用名称空间std;
sem_t s1;
sem_t s2;
void*fun1(void*i)
{

cout我不确定您是否需要两个互斥体,一个互斥体和一个条件变量以及一个额外的标志就足够了。想法是通过获取互斥体进入关键部分,然后检查是否是第一个线程,如果是,则等待条件。如果是第二个线程,则唤醒wating线程,然后两者都离开。

不使用互斥锁和锁怎么样?仅使用原子操作:

#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;
}
#包括
#包括
#包括
#包括
静态信号集;
静态易失性int _cMax=20,_cWait=0;
静态pthread_t_aThread[1000];
void*螺纹(void*idIn)
{
int nSig,iThread,cWait,id=(int)idIn;
printf(“开始%d\n”,id,cWait,_cMax);
//做些假wework
nanosleep(&(struct timespec){0,500000000},NULL);
//屏障
cWait=uuuu sync_uadd_u和fetch(&ucwait,1);
printf(“中间%d,%d/%d等待”,id,cWait,_cMax);
如果(cWait<\u cMax)
{        
//如果我们不是最后一个线程,请按信号睡眠
sigwait(&u fSigSet,&nSig);//睡眠时间
}
其他的
{
//如果我们是最后一根线,不要睡觉,不要叫醒其他人
对于(iThread=0;iThread<\u cMax;++iThread)
如果(iThread!=id)
pthread_kill(_aThread[iThread],SIGUSR1);
}
//看着他们醒来
cWait=uuuu sync_uadd_u和fetch(&ucwait,-1);
printf(“结束%d,%d/%d活动\n”,id,cWait,_cMax);
返回0;
}
int main(int argc,字符**argv)
{
pthread_attr_t attr;
int i,呃;
SIGEPTYSET(&U fSigSet);
sigaddset(&_fSigSet,SIGUSR1);
sigaddset(&U fSigSet,SIGSEGV);
printf(“开始\n”);
pthread_attr_init(&attr);
如果((err=pthread_attr_setstacksize(&attr,16384))!=0)
{
printf(“pthread_attr_setstacksize失败:错误:%d%s\n”,错误,strerror(err));
出口(0);
}
对于(i=0;i<\u cMax;i++)
{
if((err=pthread\u create(&aThread[i],&attr,thread,(void*)i))!=0)
{
printf(“pthread_在线程%d上创建失败,错误代码:%d%s\n”,i,err,strerror(err));
出口(0);
}
}
对于(i=0;i<\u cMax;++i)
pthread_join(_aThread[i],NULL);
printf(“\n完成。\n”);
返回0;
}

为什么
fun1()
fun2()
不返回
void*
!我实际上不想在循环中等待。还有其他方法吗?@akash agrawai如果你像David建议的那样使用条件变量,就不需要在循环中等待。你可以使用
pthread\u cond\u wait
@David:这是明智的解决方案(并可扩展到更多线程),但如果只允许互斥,那就有点作弊了。@john dibling我不确定,这是可能的,我的Google fu让我失望了。我很想知道。@stefaanv:我支持你。这样,我们将使用一种信号量。顺便说一句,像u sync_add_和_fetch这样的原子操作的速度只有非原子操作的2倍。同样,当我们在上面看到的sigwait方法使用互斥体/条件vs sigwait,在睡眠和唤醒线程时测试速度快40倍。