以下是我要做的事:
,这就是我需要帮助的.
我该怎么做?我看了一些pthread教程,但事情似乎很复杂,尽管我想要做的事情非常简单。
发布于 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()
挂起的线程可能在对共享资源进行一些工作并在恢复之前一直停留在线程的中间,因此彼此踩脚尖的可能性很高。
对所有其他人说:是的,打败我;-)
更新:
同等的例子:
#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;
}
预期产出:
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
...
发布于 2013-05-03 23:40:41
sleep()
和调度程序将上下文切换到另一个进程。海事组织,它不是那么糟糕的解决方案-它不是通用的,因为在某些情况下,100毫秒是很多时间,而在另一个是非常短的。发布于 2013-05-04 02:39:54
你没有很好地说明你的要求。线程是否都对独立的数据进行操作(不需要它们之间的同步)?如果是这样的话,把你自己的课程安排在10秒内的想法是荒谬的。就让他们都跑去做他们的事吧。当然,实现您所要求的使用计时器信号和控制哪些线程阻塞了信号是相当容易的,但这也是完全无用的。
另一方面,如果您的线程之间确实存在数据依赖关系,那么任何“运行10秒然后将控制权传输到另一个线程”的模式都是无效的;如果下一个线程由于第一个线程持有的锁而无法继续执行,则会导致死锁。(我认为这不是完全死锁,因为控制权最终将返回到第一个线程,但是如果涉及多个锁,延迟可能会以非常大的顺序增长。)相反,在这种情况下,您应该希望由数据流控制哪个线程运行。
https://stackoverflow.com/questions/16368653
复制相似问题