Это классический вопрос для кода повторного въезда, я знаю, но эта вещь озадачивает каждый кодер. Повторно, насколько я знаю. Кроме того, у меня очень хорошее чувство, которое я знаю, и я понимаю, что я должен сделать, чтобы сделать мой код повторным, но все же становится все сложнее, поскольку код становится все более и более сложным, а компьютерные системы развиваются.
Вопрос кажется конкретным, но на самом деле он очень широкий, поскольку он связан с прерывами, планированием задач, кэшированием и алгоритмом. Но я не хочу широкого ответа, как: «Как вы могли справиться с такими ситуациями?» Тип вопроса, но, более конкретно, Как вы можете обрабатывать повторную ценность и параллелизм в типичном многопоточном коде, как ниже, где каждый поток просто печатает простую фразу на консоли, после того как вы отправите сигнал SIGUSR1?
#define _REENTRANT
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#define STACKSIZE 16384
#define CORES_COUNT 32
#define STARTING_CORE 0
struct thread_props {
// this is the 'child_tid'
pid_t tid;
// the return value of clone, the tid if not -1
pid_t tret;
int coreID;
void* stack;
void* stack_start;
int* stopped;
// core/thread time
struct timespec start;
struct timespec end;
};
int thread_function(void* arg)
{
// get current thread properties which is passed as thread argument
struct thread_props* tprops = (struct thread_props*) arg;
// select the cpu thread/core to bind this thread
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(tprops->coreID, &cpuset);
sched_setaffinity(0, sizeof(cpuset), &cpuset);
// wait here
syscall(SYS_futex, tprops->stopped, FUTEX_WAIT, 1, NULL, NULL, 0);
// DO SOME STUFF HERE
printf("Hey it's me, Maaarioooo! ... I mean thread = %li\n",
syscall(SYS_gettid));
return 0;
}
int stopped;
void wake_threads(int sig) {
// inform that we received the signal
printf("\nSignaled to wake up the threads\n");
// do not let threads wait anymore
stopped = 0;
// wake up the waiting threads
syscall(SYS_futex, &stopped, FUTEX_WAKE, CORES_COUNT, NULL, NULL, 0);
}
int main() {
// in case all thread/cores are going to be used, then all of them
// are going to wait, so a signal to wake all threads will be handy
signal(SIGUSR1, wake_threads);
// print out the PID to know where to send signal
printf("TGID: %li\n", syscall(SYS_gettid));
// thread properties for each cpu thread/core
struct thread_props tprops[CORES_COUNT];
// set to 1 to make all threads wait
stopped = 1;
// prepare thread properties and launch threads
for(int core = STARTING_CORE; core < CORES_COUNT; ++core) {
// allocate stack memory
tprops[core].stack = mmap(NULL, STACKSIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if(tprops[core].stack == MAP_FAILED) {
perror("mmap failed");
return 1;
}
// the end of the memory is the start of the stack
tprops[core].stack_start = (tprops[core].stack + STACKSIZE);
// set the coreID so we can bind the thread to this core
tprops[core].coreID = core;
// set the wating point for the thread
tprops[core].stopped = &stopped;
// launch the thread
// since the threads are normal (detached), we need a way to wait
// for them to finish, so the CLONE_CHILD_SETTID and
// CLONE_CHILD_CLEARTID flags, will set and clear the 'child_tid'
// and we make use of futex on this and keep the return value of
// clone in a separate variable for the futex comparison
tprops[core].tret = clone(thread_function,
tprops[core].stack_start,
(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
| CLONE_IO | CLONE_VM | CLONE_FS | CLONE_FILES
| CLONE_SIGHAND | CLONE_THREAD),
&tprops[core], NULL, NULL, &tprops[core].tid);
if(tprops[core].tret == -1) {
perror("clone failed");
return 1;
}
printf("Initialized: coreID = %i\n", core);
}
// give enough time for threads to hook up
usleep(200);
// wait for all the threads to finish
// XXX: without the 'usleep' it might miss and pass through
// TODO: not thoroughly tested with usleep
for(int core = STARTING_CORE; core < CORES_COUNT; ++core)
syscall(SYS_futex, &tprops[core].tid, FUTEX_WAIT,
tprops[core].tret, NULL, NULL, 0);
// clean up
for(int i = STARTING_CORE; i < CORES_COUNT; ++i)
munmap(tprops.stack, STACKSIZE);
return 0;
}
< /code>
За исключением того, что текст на консоли очень .. очень тьфу .. уродливо из -за параллелистики, вы также заметите, что идентификаторы потока печатаются 2 и 3 раза или даже 4 иногда. < /p>
:$ ./test
TGID: 14880
Initialized: coreID = 0
Initialized: coreID = 1
Initialized: coreID = 2
Initialized: coreID = 3
Initialized: coreID = 4
Initialized: coreID = 5
Initialized: coreID = 6
Initialized: coreID = 7
Initialized: coreID = 8
Initialized: coreID = 9
Initialized: coreID = 10
Initialized: coreID = 11
Initialized: coreID = 12
Initialized: coreID = 13
Initialized: coreID = 14
Initialized: coreID = 15
Initialized: coreID = 16
Initialized: coreID = 17
Initialized: coreID = 18
Initialized: coreID = 19
Initialized: coreID = 20
Initialized: coreID = 21
Initialized: coreID = 22
Initialized: coreID = 23
Initialized: coreID = 24
Initialized: coreID = 25
Initialized: coreID = 26
Initialized: coreID = 27
Initialized: coreID = 28
Initialized: coreID = 29
Initialized: coreID = 30
Initialized: coreID = 31
Signaled to wake up the threads
Hey it's me, Maaarioooo! ... I mean thread = 14884
Hey it's me, Maaarioooo! ... I mean thread = 14884
Hey it's me, Maaarioooo! ... I mean thread = 14894
Hey it's me, Maaarioooo! ... I mean thread = 14890
Hey it's me, Maaarioooo! ... I mean thread = 14893
Hey it's me, Maaarioooo! ... I mean thread = 14890
Hey it's me, Maaarioooo! ... I mean thread = 14883
Hey it's me, Maaarioooo! ... I mean thread = 14889
Hey it's me, Maaarioooo! ... I mean thread = 14892
14891
Hey it's me, Maaarioooo! ... I mean thread = 14896
Hey it's me, Maaarioooo! ... I mean thread = 14896
Hey it's me, Maaarioooo! ... I mean thread = 14881
Hey it's me, Maaarioooo! ... I mean thread = 14896
Hey it's me, Maaarioooo! ... I mean thread = 14881
Hey it's me, Maaarioooo! ... I mean thread = 14897
Hey it's me, Maaarioooo! ... I mean thread = 14897
Hey it's me, Maaarioooo! ... I mean thread = 14899
Hey it's me, Maaarioooo! ... I mean thread = 14900
Hey it's me, Maaarioooo! ... I mean thread = 14895
Hey it's me, Maaarioooo! ... I mean thread = 14898
Hey it's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = 14885
14907
's me, Maaarioooo! ... I mean thread = 14885
14907
14907
's me, Maaarioooo! ... I mean thread = 14885
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
1491114907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
14911
s me, Maaarioooo! ... I mean thre
4904
14907
's me, Maaarioooo! ... I mean thread = 14885
Hey it's me, Maaarioooo! ... I mean thread = Hey it's me, Maaarioooo! ... I mean thread = Hey i
< /code>
Ожидается, что схватка текста, но он работает более одного раза, заставляет мою голову зудеть. Существуют простые, но грязные способы, а также есть более сложные, но приличные способы исправить это, но нет стандартного чистого способа. < /P>
Если там это способ, пожалуйста, просветите меня! Спасибо!
Подробнее здесь: https://stackoverflow.com/questions/794 ... cause-of-i
Это странное поведение с функциями, называемыми дважды (или «возобновляется») из -за прерываний. Как я предполагаю, что ⇐ Linux
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Являются ли оба так называемыми свойствами или они чем-то отличаются? [дубликат]
Anonymous » » в форуме C# - 0 Ответы
- 17 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Являются ли оба так называемыми свойствами или они чем-то отличаются? [дубликат]
Anonymous » » в форуме C# - 0 Ответы
- 8 Просмотры
-
Последнее сообщение Anonymous
-