Avatar billede don_r Nybegynder
30. november 2004 - 19:15 Der er 17 kommentarer og
1 løsning

threads i c/c++

Hej Alle

Herunder er et uddrag af en klasse(Listner), startListen skal oprette en ny tråd, men jeg har problemer med at få overført args på en rigtig måde. Er der helt forkert det jeg gør, er der en anden måde ect.

void Listner::startListen(int _port){
    pthread_t serveThread;
    INetSocket listen(_port);
    INetSocket* newSocket = new INetSocket;
   
    listen.Listen(10);
    while(true){
        listen.Accept(newSocket);
        pthread_create(&serveThread, NULL, serveClient, (void*)newSocket);
    }
}

void* Listner::serveClient(void* _socket){
    INetSocket a = (INetSocket *)_socket;  // denne viker ikke... Hvorfor ?
    ServeClient* client = new ServeClient;    
    client->setINetSocket(a); // tager en INetSocket*  - (pointer)
    client->startServe();
}
Avatar billede arne_v Ekspert
30. november 2004 - 19:17 #1
Jeg tror at det sidste argument er OK.

Men jeg tror at det næst sidste argument driller.

Man kan ikke overføre en ikke static metode som argument til en anden metode.
Avatar billede arne_v Ekspert
30. november 2004 - 19:24 #2
Jeg forudsætter at serveClient ikke er static.

Du kan prøve noget a la dette:

struct stor
{
  Listner *l;
  INetSocket *s;
}

void dispatch(void *arg)
{
  stor *arg2 = (stor *) arg;
  arg->l->serveClient(arg->s);
}

...

stor data;
data.l = this;
data.s = newSocket;
pthread_create(&serveThread, NULL, dispatch, (void*)&data);

[utestet - bare tastet ind]
Avatar billede don_r Nybegynder
30. november 2004 - 19:31 #3
Men det er faktisk kun en pointer til en INetSocket jeg ønsker at overføre som arg, in funktionen ønsker jeg at kalde en funktion fra en anden klasse med den. Er der en nem måde at gøre dette ?...

Jeg har ikke meget styr på det åbenbart.
Avatar billede don_r Nybegynder
30. november 2004 - 19:34 #4
ok jeg kan godt se hvad du gør, men er det nødvendigt med den struct ??
Avatar billede arne_v Ekspert
30. november 2004 - 19:37 #5
Hvis Listner::serveClient er static så nej ellers ja.
Avatar billede don_r Nybegynder
30. november 2004 - 19:45 #6
Listner::serveClient er static
Avatar billede don_r Nybegynder
30. november 2004 - 19:46 #7
#ifndef LISTNER_H
#define LISTNER_H

#include <iostream>
#include "INetSocket.h"
using namespace std;

class Listner {
    public:
        Listner();
        void startListen(int _port);
    private:
        static void* serveClient(void* _socket);       
};
#endif
Avatar billede arne_v Ekspert
30. november 2004 - 19:47 #8
OK - så glemmer du lige alt det jeg har skrevet hidtil !
Avatar billede arne_v Ekspert
30. november 2004 - 19:48 #9
Skal

INetSocket a = (INetSocket *)_socket;

ikke være

INetSocket *a = (INetSocket *)_socket;

eller

INetSocket a = *((INetSocket *)_socket);
Avatar billede don_r Nybegynder
30. november 2004 - 19:50 #10
Nu har jeg gjort sådanne, det ser ud til at virke...

void Listner::startListen(int _port){
    pthread_t serveThread;
    INetSocket listen(_port);
   
   
    listen.Listen(10);
    while(true){
        INetSocket* newSocket = new INetSocket;
        listen.Accept(newSocket);
        pthread_create(&serveThread, NULL, serveClient, newSocket);
    }
}

void* Listner::serveClient(void* _socket){
    INetSocket *a = (INetSocket *) _socket;
    ServeClient* client = new ServeClient;    
    client->setINetSocket(a);
    client->startServe();
}
Avatar billede don_r Nybegynder
30. november 2004 - 19:50 #11
nååå det har du lige skrevet, jeg synes bare lige at jeg havde prøvet det meeennn
Avatar billede don_r Nybegynder
30. november 2004 - 19:53 #12
smid lige et svar så får du dine point. En anden ting, kan du hurtigt sige om vi får problemer hvis vi laver det på den måde. Jeg er bange for at de forskellige clienter kommer til at bruge samme socket (ligger i INetSocket).

Jeg har set noget der så ud som at der først bliv tjekket om den socket man ville bruge er fri, giver det nogen menning ? Det er helt i orden hvid det er til et andet spg.
Avatar billede arne_v Ekspert
30. november 2004 - 19:57 #13
accept create er ny socket og den bliver vel kopieret med rundt i din
INetSocket, så medmindre du har lavet en bøf i det, så bør det virke og
hver sin client have hver sin socket.

En bøf kunne f.eks. være en copy constrctor eller en = operator.
Avatar billede arne_v Ekspert
30. november 2004 - 19:57 #14
og et svar
Avatar billede don_r Nybegynder
30. november 2004 - 20:03 #15
En sidste ting, nu ved jeg godt at at jeg driver rovdrift på dig.

Meeennn: når jeg har serviceret min socket, vil jeg gerne nedlægge den thread jeg laver, sker det automatisk eller skal jeg nedlægge den.

Ala

void* Listner::serveClient(void* _socket){
    INetSocket *a = (INetSocket *) _socket;
    ServeClient* client = new ServeClient;   
    client->setINetSocket(a);
    client->startServe();
    pthread_exit(0);

}
Avatar billede arne_v Ekspert
30. november 2004 - 20:05 #16
Det burde være nok bare at lave:

void* Listner::serveClient(void* _socket){
  ...
  return NULL;
}
Avatar billede arne_v Ekspert
30. november 2004 - 20:07 #17
Fra noget docs:

An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it. The function's return value serves as the thread's exit status.
Avatar billede don_r Nybegynder
30. november 2004 - 20:08 #18
ok lyder godt.

Mange tak
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester