Поток - синхронизирующий и спящий поток отказывается просыпаться (LINUX) - PullRequest
2 голосов
/ 03 апреля 2012

Я разрабатываю приложение для OpenSUSE 12.1.

В этом приложении есть основной поток и два других потока, в которых выполняются экземпляры тех же функций.Я пытаюсь использовать pthread_barrier для синхронизации всех потоков, но у меня возникают некоторые проблемы:

  1. Когда я отправляю производные потоки в спящий режим, по какой-то причине они никогда не проснутся.
  2. (в случае, когда я удаляю сон из других потоков, выбрасывая использование процессора в небо) В какой-то момент все потоки достигают pthread_barrier_wait(), но ни один из них не продолжает выполнение после этого.

Вот некоторый псевдокод, пытающийся проиллюстрировать, что я делаю.

pthread_barrier_t barrier;
int main(void)
{
    pthread_barrier_init(&barrier, NULL , 3);
    pthread_create(&thread_id1, NULL,&thread_func, (void*) &params1);
    pthread_create(&thread_id2v, NULL,&thread_func, (void*) &params2);

    while(1)
    {
        doSomeWork();
        nanosleep(&t1, &t2);

        pthread_barrier_wait(&barrier);

        doSomeMoreWork();
   }
}

void *thread_func(void *params)
{
    init_thread(params);

    while(1)
    {
        nanosleep(&t1, &t2);
        doAnotherWork();

        pthread_barrier_wait(&barrier);
    }
}

Ответы [ 2 ]

0 голосов
/ 04 апреля 2012

Я бы предложил использовать условные переменные для синхронизации потоков. Вот какой-то сайт о том, как это сделать, надеюсь, это поможет.

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

0 голосов
/ 03 апреля 2012

Я не думаю, что это связано с барьером, как вы представили его в псевдокоде.Я предполагаю, что ваш glibc примерно такой же, как моя машина.Я примерно скомпилировал ваш псевдокод, и он работает так, как я ожидаю: потоки выполняют некоторую работу, основной поток выполняет некоторую работу, все они достигают барьера и затем зацикливаются.

Можете ли вы прокомментировать больше о любой другой синхронизацииметоды или каковы рабочие функции?

Это пример программы, которую я использую:

#include <pthread.h>
#include <stdio.h>
#include <time.h>

struct timespec req = {1,0}; //{.tv_sec = 1, .tv_nsec = 0};
struct timespec rem = {0,0}; //{.tv_sec = 0, .tv_nsec = 0};

pthread_barrier_t barrier;

void *thread_func(void *params) {
   long int name;
   name = (long int)params;
   while(1) {
      printf("This is thread %ld\n", name);
      nanosleep(&req, &rem);

      pthread_barrier_wait(&barrier);

      printf("More work from %ld\n", name);
   }
}

int main(void)
{
   pthread_t th1, th2;

   pthread_barrier_init(&barrier, NULL , 3);
   pthread_create(&th1, NULL, &thread_func, (void*)1);
   pthread_create(&th2, NULL, &thread_func, (void*)2);

   while(1) {
      nanosleep(&req, &rem);
      printf("This is the parent\n\n");

      pthread_barrier_wait(&barrier);
   }
   return 0;
}
...