如何使循环的一部分仅在其中一名工人中执行?

发布于 2025-02-09 21:19:11 字数 703 浏览 3 评论 0原文

我有一个循环打开与远程SFTP服务器的多个连接。每个会话都需要验证远程主机的密钥,但是现有的键列表仅需要加载曾经

我正在使用的libssh2 API需要一个现有的会话来加载列表,因此在进入循环之前,我无法阅读 - 因为在其中初始化了会话。

是否有布拉格马斯,可以让我这样做:

  1. 制作一个线程之一 - 我不在乎,哪一个 - 加载〜/.ssh/nownow_hosts
  2. 使所有其他线程都等待 做到了吗?

我尝试了:

    #pragma omp for
    for (i = 0; i < jobs; i++) {
        sessions[i] = libssh2_session_init();
        ...
        #pragma omp task
        {
            known = load_known_hosts(sessions[i], ...);
        }

        #pragma omp taskwait
        check_known_hosts(known, ...);
        ...
    }

此编译,但无法按预期工作 - 当check_noyne_hosts()试图使用它时,列表仍未实现。

I have a loop opening multiple connections to a remote SFTP-server. Each session needs to verify the remote host's key, but the existing list of keys only needs to be loaded once.

The libssh2 API I'm using requires an existing session for loading the list, so I cannot read it before entering into the loop -- as the sessions are initialized inside it.

Are there pragmas, that'll allow me to:

  1. Make one of threads -- I don't care, which one -- load the ~/.ssh/known_hosts.
  2. Cause all of the other threads to wait for that lucky one to do it?

I tried:

    #pragma omp for
    for (i = 0; i < jobs; i++) {
        sessions[i] = libssh2_session_init();
        ...
        #pragma omp task
        {
            known = load_known_hosts(sessions[i], ...);
        }

        #pragma omp taskwait
        check_known_hosts(known, ...);
        ...
    }

This compiles, but does not work as intended -- the list is still uninitialized, when the check_known_hosts() tries to use it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

写给空气的情书 2025-02-16 21:19:11

我的建议是以下内容(类似于 @ deamcrash 建议,但也可以并行进行初始化)

#pragma omp parallel
{
    ...
    #pragma omp for
    for (i = 0; i < jobs; i++) {
    //initialization in parallel
    sessions[i] = libssh2_session_init();
    ...
    }

    #pragma omp single
    {
        // work done by a single thread 
        known = load_known_hosts(...);
        ...
    }

    #pragma omp for
    for (i = 0; i < jobs; i++) {
        //other parallel work
        check_known_hosts(known, ...);
        ....
    }
    ...
}

My suggestion is the following (similar to what @deamcrash suggested, but initialization can also be done in parallel)

#pragma omp parallel
{
    ...
    #pragma omp for
    for (i = 0; i < jobs; i++) {
    //initialization in parallel
    sessions[i] = libssh2_session_init();
    ...
    }

    #pragma omp single
    {
        // work done by a single thread 
        known = load_known_hosts(...);
        ...
    }

    #pragma omp for
    for (i = 0; i < jobs; i++) {
        //other parallel work
        check_known_hosts(known, ...);
        ....
    }
    ...
}
明媚如初 2025-02-16 21:19:11

如果没有更多的上下文,我会去做:

    #pragma omp single
    {
        sessions[0] = libssh2_session_init();
        ...
        known = load_known_hosts(sessions[0], ...);
        ...
        check_known_hosts(known, ...);
        ...
    }

    #pragma omp for
    for (i = 1; i < jobs; i++) {
        sessions[i] = libssh2_session_init();
        ...
        check_known_hosts(known, ...);
        ...
    }

我会从循环中提取第一个迭代,在并行循环之前执行,然后执行循环。为了使其清洁,您可以从每个循环迭代中执行的代码中提取一种方法。

Without more context I would go for:

    #pragma omp single
    {
        sessions[0] = libssh2_session_init();
        ...
        known = load_known_hosts(sessions[0], ...);
        ...
        check_known_hosts(known, ...);
        ...
    }

    #pragma omp for
    for (i = 1; i < jobs; i++) {
        sessions[i] = libssh2_session_init();
        ...
        check_known_hosts(known, ...);
        ...
    }

I would extract the first iteration out of the loop, executed before the parallel loop, and then execute the loop. To make it clean you could extract a method out of the code being executed in each loop iteration.

稀香 2025-02-16 21:19:11

我快速而肮脏的“解决方案”是为第一份工作加载清单 - 如果其他工人在Job-0之前到达这一点,请旋转:

    if (i == 0) {
        known = load_known_hosts(sessions[0], ...);
        if (known == NULL)
            errx(EX_SOFTWARE, "Couldn't load known hosts");
    } else while (known == NULL)
        pthread_yield();

我敢肯定,有一种方法可以做到这一点适当地 - 带有OpenMP pragmas-因此等待适当的答案。

My quick and dirty "solution" was to load the list for the first job only -- and make other workers spin, if they arrive to this point before the job-0 does:

    if (i == 0) {
        known = load_known_hosts(sessions[0], ...);
        if (known == NULL)
            errx(EX_SOFTWARE, "Couldn't load known hosts");
    } else while (known == NULL)
        pthread_yield();

I'm sure, there is a way to do this properly -- with OpenMP pragmas -- so awaiting the proper answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文