首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在posix线程之间切换?

如何在posix线程之间切换?
EN

Stack Overflow用户
提问于 2013-05-03 22:51:42
回答 3查看 4.9K关注 0票数 0

以下是我要做的事:

  1. 从主线程启动10个posix线程。
  2. 这10个线程中的每一个都会执行一些操作,比如100次。

,这就是我需要帮助的.

  1. 我希望允许thread_1做它的事情,比如10秒(当线程2-10被挂起时),然后让线程2去做它的事情,而线程1和线程3-10被挂起等等。

我该怎么做?我看了一些pthread教程,但事情似乎很复杂,尽管我想要做的事情非常简单。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-04 11:08:15

除了讨论“任择议定书”的问题是否有意义外,一个可能的解决办法是:

为要调度的每个线程安装一个信号处理程序。这个处理程序是在例如SIGUSR1上触发的,在内部只会调用对pause()的调用。

线程函数都以对pause()的调用开始,该调用在创建后立即挂起所有线程。

使用pthread_create()创建所有线程为计划。将创建的线程存储到数组pthreads中。

将要运行的第一个线程(从pthread)分配给pthread_first

要开始调度,请调用pthread_kill(pthread_first, SIGUSR2)以恢复要首先运行的线程(将pause()设置为阻塞以返回)。使pthread_current成为pthread_first

要实际执行调度,额外的线程(可能是主线程)会无限循环并调用sleep(SCHEDULING_INTERVALL),然后调用pthread_kill(pthread_current, SIGUSR1)来挂起当前线程(通过调用其信号处理程序并将其运行到pause()中)。然后调用pthread_kill(pthread_next, SIGUSR2)继续下一个线程(通过使pause()阻塞以返回)。使pthreat_current成为pthread_next,而pthread_next成为线程创建期间填充的数组pthread中的另一个条目。

但请注意:

由于由信号插入并由pause()挂起的线程可能在对共享资源进行一些工作并在恢复之前一直停留在线程的中间,因此彼此踩脚尖的可能性很高。

对所有其他人说:是的,打败我;-)

更新:

同等的例子:

代码语言:javascript
运行
复制
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>

#define THREADSMAX (3)
#define SCHEDULING_INTERVALL (5) /* seconds */

void
sigusr_handler(int signo)
{
  if (SIGUSR1 == signo)
    {
      pause();
    }
}

void *
thread_function(void * pv)
{
  intptr_t iThread = (intptr_t) pv;

  pause();

    {
      int i = 0;
      for (;;)
        {
          printf("%d: %d\n", (int) iThread, i++);
          sleep(1);
        }
    }

  pthread_exit(NULL);
}

int
main(int argc, char ** argv)
{
  struct sigaction signal_action;
  memset(&signal_action, 0, sizeof(signal_action));
  signal_action.sa_handler = sigusr_handler;
  sigemptyset(&signal_action.sa_mask);

  sigaction(SIGUSR1, &signal_action, NULL);
  sigaction(SIGUSR2, &signal_action, NULL);

    {
      pthread_t threads[THREADSMAX] =
        { 0 };

      intptr_t iThread = 0;

      /* create threads */
      for (; iThread < THREADSMAX; ++iThread)
        {
          int iResult = pthread_create(&threads[iThread], NULL, thread_function,
              (void *) iThread);
          if (iResult)
            {
              errno = iResult;
              perror("pthread_created()");
              exit(1);
            }
        }

      sleep(1); /* Unreliable workaround: Try to make sure all threads have started and block in "pause()". See comments on how this might be fixed nicely ... */

      /* scheduling loop */
      for (iThread = 0;; ++iThread)
        {
          if (THREADSMAX == iThread)
            {
              iThread = 0;
            }
            /* Resume current thread */
            {
              int iResult = pthread_kill(threads[iThread], SIGUSR2);
              if (iResult)
                {
                  errno = iResult;
                  perror("pthread_kill(..., SIGUSR2)");
                  exit(2);
                }
            }

          sleep(SCHEDULING_INTERVALL);

          /* Suspend current thread */
            {
              int iResult = pthread_kill(threads[iThread], SIGUSR1);
              if (iResult)
                {
                  errno = iResult;
                  perror("pthread_kill(..., SIGUSR1)");
                  exit(3);
                }
            }
        }
    }

  return 0;
}

预期产出:

代码语言:javascript
运行
复制
0: 0
0: 1
0: 2
0: 3
0: 4
1: 0
1: 1
1: 2
1: 3
1: 4
2: 0
2: 1
2: 2
2: 3
2: 4
0: 5
0: 6
0: 7
0: 8
0: 9
1: 5
1: 6
1: 7
1: 8
1: 9
2: 5
2: 6
...
票数 3
EN

Stack Overflow用户

发布于 2013-05-03 23:40:41

  1. POSIX线程:条件变量-有什么意义?
  2. 螺纹连接与分离
  1. 使用sleep()和调度程序将上下文切换到另一个进程。海事组织,它不是那么糟糕的解决方案-它不是通用的,因为在某些情况下,100毫秒是很多时间,而在另一个是非常短的。
  2. 由我们自己的条件变量或某种同步器实现- -但这确实是不推荐的。
票数 1
EN

Stack Overflow用户

发布于 2013-05-04 02:39:54

你没有很好地说明你的要求。线程是否都对独立的数据进行操作(不需要它们之间的同步)?如果是这样的话,把你自己的课程安排在10秒内的想法是荒谬的。就让他们都跑去做他们的事吧。当然,实现您所要求的使用计时器信号和控制哪些线程阻塞了信号是相当容易的,但这也是完全无用的。

另一方面,如果您的线程之间确实存在数据依赖关系,那么任何“运行10秒然后将控制权传输到另一个线程”的模式都是无效的;如果下一个线程由于第一个线程持有的锁而无法继续执行,则会导致死锁。(我认为这不是完全死锁,因为控制权最终将返回到第一个线程,但是如果涉及多个锁,延迟可能会以非常大的顺序增长。)相反,在这种情况下,您应该希望由数据流控制哪个线程运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16368653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档