Это странное поведение с функциями, называемыми дважды (или «возобновляется») из -за прерываний. Как я предполагаю, что Linux

Ответить Пред. темаСлед. тема
Anonymous
 Это странное поведение с функциями, называемыми дважды (или «возобновляется») из -за прерываний. Как я предполагаю, что

Сообщение Anonymous »

Это классический вопрос для кода повторного въезда, я знаю, но эта вещь озадачивает каждый кодер. Повторно, насколько я знаю. Кроме того, у меня очень хорошее чувство, которое я знаю, и я понимаю, что я должен сделать, чтобы сделать мой код повторным, но все же становится все сложнее, поскольку код становится все более и более сложным, а компьютерные системы развиваются.
Вопрос кажется конкретным, но на самом деле он очень широкий, поскольку он связан с прерывами, планированием задач, кэшированием и алгоритмом. Но я не хочу широкого ответа, как: «Как вы могли справиться с такими ситуациями?» Тип вопроса, но, более конкретно, Как вы можете обрабатывать повторную ценность и параллелизм в типичном многопоточном коде, как ниже, где каждый поток просто печатает простую фразу на консоли, после того как вы отправите сигнал 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»