Ошибка pthread_create в C ++ (pthread внутри класса) - PullRequest
2 голосов
/ 28 апреля 2011

У меня есть этот код C ++, где я пытаюсь создать pthread, и я получил 4 ошибки:

Может кто-нибудь помочь, пожалуйста?

Заранее спасибо.

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

static void* func(void*);

class Test
{
 public:
    pthread_t *threadId;
    pthread_create(threadId, NULL, func, NULL);

 };

 static void* func(void *arg)
 {
   printf("Thread function called\n");
 }

 int main()
 {
  Test();
 }

Компиляция:

 # g++ simplepThread.cc -lpthread
      simplepThread.cc:11: error: ‘threadId’ is not a type
      simplepThread.cc:11: error: expected identifier before ‘__null’
      simplepThread.cc:11: error: expected ‘,’ or ‘...’ before ‘__null’
      simplepThread.cc:11: error: ISO C++ forbids declaration of ‘pthread_create’ with no type

Если я использую функцию потока в качестве связи "C":

extern "C" void* func(void *arg)
{
  printf("Thread function called\n");
}

Произошла ошибка:

simplepThread.cc:7: error: previous declaration of ‘void* func(void*)’ with ‘C++’ linkage
simplepThread.cc:15: error: conflicts with new declaration with ‘C’ linkage

Ответы [ 2 ]

2 голосов
/ 28 апреля 2011

Существует ряд проблем с вашим кодом. Прежде всего, вам нужно объявить функцию конструктора для класса Test, и учитывая то, как вы использовали код, я бы поместил вызов pthread_create () внутри конструктора. Во-вторых, хотя pthread_create () принимает в качестве своего первого аргумента аргумент pthread_t *, это означает, что этот аргумент используется в качестве выходного параметра, и указатель должен указывать на фактическую память / переменную, где идентификатор потока для вновь созданного потока будет помещается.

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

static void* func(void*);

class Test
{
 public:
    pthread_t threadId;

    Test() {
       pthread_create(&threadId, NULL, func, NULL);
    }
 };

 static void* func(void *arg)
 {
   printf("Thread function called\n");
 }

 int main()
 {
  Test();
 }

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

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

2 голосов
/ 28 апреля 2011

Вы не можете вызывать функции в объявлении класса.В объявлении класса вы можете только объявить (и, возможно, определить) его члены.И

pthread_create(threadId, NULL, func, NULL);

не является допустимым определением функции-члена.
Весь класс Test представляется избыточным.

static void* func(void *arg)
{
   printf("Thread function called\n");
}
int main()
{
  pthread_t threadId;

  pthread_create(&threadId, NULL, func, NULL);
}

Должно работать нормально.
Я исправил и другоепроблема - вы попытались передать неинициализированный указатель (threadId) в функцию, которая ожидает адрес переменной.
ОБНОВЛЕНИЕ
О связи - у вас есть прототип со значением по умолчанию (связь C ++)

void* func(void *arg);

И определение со связью C

extern "C"
{
    void* func(void *arg)
    {
    ....
    }
}

Так что они конфликтуют.измените прототип на

extern "C"
{
  void* func(void *arg);
}

и все будет в порядке

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...