pthread_cond_wait() не заставляет процессор спать?
Все
У меня есть вопрос о pthread_cond_wait(). Короче говоря, я создаю два потока POSIX в процессе. Если я выполняю следующий код, почему загрузка ЦП полна?
Я провожу эксперименты на нем, если я удаляю отметку комментария до того, как bool isNodeConnect3, программа, похоже, не вызывает проблем, загрузка ЦП составляет почти 0%, другими словами, thead перейдет в спящий режим и не будет тратить ресурсы ЦП, это то, что я хочу.
Это проблема с данными? возможно, но я так не думаю, потому что я заключаю в скобки свою структуру с помощью "#pragma pack(push,1) ... #pragma (pop)" "Не могли бы вы дать мне предложение??
Среда Хост-ОС - это win7/intel 64 bit, гостевая ОС - ubuntu 10.04LTS. Предоставьте гостевым ОС "количество ядер процессора:4". Ниже приведен мой тестовый код, его можно собрать и запустить с помощью:
gcc -o program1 program1.c -pthread && ./program1 Получить использование ЦП составляет 25%. Результат зависит от ваших настроек.
Большое спасибо.
Код
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <stdbool.h>
#pragma pack(push,1)
struct BUFF_TX{
pthread_mutex_t mutex_lock;
pthread_cond_t more;
};
struct AtreeNode{
struct BUFF_TX buff_tx;
bool isNodeConnect;
bool isNodeConnect1;
bool isNodeConnect2;
// bool isNodeConnect3; // important
pthread_t thrd_tx;
};
struct AtreeNode treeNode[2];
int tmp[2];
#pragma (pop)
void Thread_TX(int *nodeIdx)
{
int idx = *nodeIdx;
while(1)
{
printf("Thread %d enter mutex lock...\n", idx);
pthread_mutex_lock(&treeNode[idx].buff_tx.mutex_lock);
while(1)
{
if(idx==0)
{
printf("idx==0 wait...\n");
pthread_cond_wait(&(treeNode[0].buff_tx.more), &treeNode[idx].buff_tx.mutex_lock);
}
else if(idx==1)
{
printf("idx==1 wait...\n");
pthread_cond_wait(&(treeNode[1].buff_tx.more), &treeNode[idx].buff_tx.mutex_lock);
}
else
printf("err\n");
}
pthread_mutex_unlock(&treeNode[idx].buff_tx.mutex_lock);
printf("Thread %d leave mutex lock...\n", idx);
}
}
int main(int argc, char *argv[])
{
int i;
int ret;
tmp[0] = 0;
tmp[1] = 1;
for(i=0; i<2; i++)
{
if(pthread_cond_init(&treeNode[i].buff_tx.more, NULL) != 0)
{
printf("cond %d init fail.\n", i);
exit(EXIT_FAILURE);
}
if(pthread_mutex_init(&treeNode[i].buff_tx.mutex_lock, NULL) != 0)
{
printf("mutex lock %d init fail.\n", i);
exit(EXIT_FAILURE);
}
}
for(i=0; i<2; i++)
{
ret = pthread_create(&treeNode[i].thrd_tx, NULL, (void *)Thread_TX, (void *)(&tmp[i]));
if(ret)
{
printf("pthread_create thrd_tx %d err\n", i);
return false;
}
}
pthread_join(treeNode[0].thrd_tx, NULL);
pthread_join(treeNode[1].thrd_tx, NULL);
exit(EXIT_SUCCESS);
}
1 ответ
Удалить #pragma pack(1)
и забудь, что ты когда-либо слышал об этом. Ваша проблема в том, что вы передаете неверный указатель на pthread_cond_wait
, pthread_cond_t
имеет определенное требование выравнивания, и вы создаете объекты, которые не обязательно соответствуют этому требованию, и, следовательно, их адреса недопустимы для передачи pthread_cond_wait
, См. Также https://sourceware.org/bugzilla/show_bug.cgi?id=16549 который был РАЗРЕШЕН при перемещении в отчет об ошибках в GCC за то, что он не перехватил использование недопустимого указателя.
Вы должны быть в состоянии подтвердить, является ли это реальной причиной вашей проблемы, запустив программу под strace -f
и видя, что futex
системные вызовы терпят неудачу с EINVAL
или похожие.