简体   繁体   English

如何在用作tcp服务器的线程中使用带有函数参数的函数

[英]How to use a function which takes a function parameter, in a thread that is used as a tcp server

And I have to create a thread inside a function, that is (the thread) in an infinite loop waiting for connections and accepting messages from another process (so, the thread is going to work as a tcp server), and whenever a message comes, it has to ¿use? 而且我必须在函数内部创建一个线程,即在无限循环中的(线程)等待连接并接受来自另一个进程的消息(因此,该线程将作为tcp服务器工作),并且无论何时出现消息,它必须使用? or call or whatever the function that's passed as a parameter, to the function the thread is created in. 或调用或将作为参数传递的任何函数传递给在其中创建线程的函数。

So this is the function header 这就是函数头

 int init(void (*notif)(const char *, const char *),
            void (*parameter1)(const char *),
            void (*parameter2)(const char *));

So I've seen this post How do you pass a function as a parameter in C? 所以我看过这篇文章如何在C中将函数作为参数传递? and it kind of helps to get the idea but I'm completly unsure how would I do it inside a thread. 并有助于获得想法,但我完全不确定如何在线程中实现它。

And the reason for that is because I have little to no experience with servers inside threads, I found this code which is really helpful https://gist.github.com/silv3rm00n/5821760 这样做的原因是因为我对线程内部的服务器几乎没有经验,所以我发现这段代码非常有用https://gist.github.com/silv3rm00n/5821760

But the way it works, all of the code is in the function (so outside the thread) and the thread takes as the only parameter the socket used for connections. 但是,按照其工作方式,所有代码都在函数中(因此在线程之外),并且线程将用于连接的套接字作为唯一参数。 I've seen it used similar to this a few times already. 我已经看过几次类似的用法。

And then I doubt: does it make sense to put all of the code of the server inside the thread? 然后我怀疑:将服务器的所有代码放入线程内是否有意义? Or it would make little sense and the thread would be too "heavy" and it would be better to fork in that case. 否则,它将变得毫无意义,并且线程太“重”,在这种情况下最好进行分叉。

I'm sorry if the question is poorly worded or I'm not explaining myself properly, I have little experience with threads and 0 experience with this type of problems. 如果问题措辞不佳或我没有正确解释自己,我很抱歉,我对线程的经验很少,对此类问题的经验为0。

edit: this is all I've got so far but I'm missing something, it does not work: 编辑:这是我到目前为止所拥有的,但是我缺少了一些东西,它不起作用:

void (*funcionParametroThread)(const char *, const char *);
funcionParametroThread=(*notif_evento)(const char *, const char *);
pthread_create(&thid, &atrib_th, tcp_server, funcionParametroThread);

I tried making it similar to this code that is an answer from the linked question above 我试图使它类似于此代码,它是上面链接的问题的答案

int dosomethingwithchar(char a) { return 1; }
functiontype2 func2 = &dosomethingwithchar
int result = func2('a');

(Keep in mind that I'm writing on the fly) (请记住,我正在即时写作)

A thread (linux pthread) as normally this signature: 一个线程(linux pthread)通常具有以下特征:

void * threadName(void *parms)

It's started by the function pthread_create that starts it passing parms. 它由函数pthread_create启动,该函数通过传递parms来启动它。

typedef void * THFN_t(void *parms)

struct thStruct {
 volatile int a; //volatile because the value may change during inter-process!
 volatile int b;
 volatile int c;
};

void * thread(struct thStruct *k) 
{
    for(;;) {
       /* do your job */
    }

    pthread_exit(NULL);
}

int main(void) 
{
   struct thStruct s;

   s.a=1; //These structure will be passed to the thread
   s.b=2;
   s.c=3;

   pthread_attr_t attr;
    pthread_t thr;
   pthread_attr_init(attr);
    if (pthread_create(
                (pthread_t*)&thr,
                (pthread_attr_t*)&attr,
                (THFN_t *)thread, //The function above
                (void *)&s)) {
                     perror("Error");
                     return errno;
      }

      while(s.a!=0) { //Used to lock the main, but also to pass something to the thread!
         printf("Insert a number: ");
         scanf("%d",s.a);
      }
}

This is the skeleton that contains hints to explain you how to pass information to a running thread. 这是包含提示的骨架,以解释如何将信息传递给正在运行的线程。 Remember the volatile and remember that some changes may be executed as atomic (you might use mutex to change them in the correct way). 记住volatile,并记住某些更改可能是原子执行的(您可以使用互斥锁以正确的方式更改它们)。

I understand you need to inform your thread that it has to call a function and you need this function be a parameter. 我了解您需要通知线程它必须调用一个函数,并且您需要将此函数作为参数。

I hope this function will have a fixed number of parameter ... :) 我希望这个函数将有固定数量的参数... :)

We say that the function we will call will have this signature: 我们说我们将调用的函数将具有以下签名:

int fnname(int a, char *b);

Then we declare (I prefer so): 然后我们声明(我更喜欢这样):

typedef int FNX(int a, char *b);

Then we insert in the structure thStruct an element that specifies a pointer to the function we want call. 然后,在结构thStruct中插入一个元素,该元素指定指向要调用的函数的指针。

struct thStruct {
 volatile int a; //volatile because the value may change during inter-process!
 volatile int b;
 volatile int c;
 volatile FNX * fn; //Function pointer
};

Now we need the function: 现在我们需要函数:

int functionX(int a, char *b)
{
   printf("%d %s\n",a,b);
}

Next step: In the main, where we have initialized the thStruct, we want signal what function the thread will be call when a specific event occurs (for example sa becomes 5) 下一步:在主线程中,我们已经初始化了thStruct,在发生特定事件(例如sa变为5)时,我们希望发出信号该线程将被调用的函数

Ok: 好:

we add: 我们增加:

s.fn=functionX;

Now we modify the thread: 现在我们修改线程:

void * thread(struct thStruct *k) 
{
    for(;;) {
       if (k->a==5) {
          k->fn(a,"Yeah!\n");
          k->a=4; //To avoid continue calling k->fn
       }
       sched_yield(); //To avoid useless use of CPU time
                      //(this thread does nothing and waits for nothing!)
    }

    pthread_exit(NULL);
}

Now, if the program doesn't contain errors, you may compile it (I think you may solve if errors occurs) and will run. 现在,如果程序不包含错误,则可以对其进行编译(我认为您可以解决是否发生错误)并可以运行。

When it will ran, you may insert 5 when main asks you a number and the function functionX will be called! 当它运行时,您可以在main询问您一个数字时插入5,然后将调用函数functionX!

How I said you, I've written this code on the fly to help you. 我是怎么说的,我已经即时编写了这段代码来帮助您。 It may contain errors, but it should be able to explain some basilar things you need. 它可能包含错误,但是它应该能够解释您需要的一些基础知识。 There's more, but I think this give you a good way! 还有更多,但是我认为这给您一个好方法!

This is the end!!! 这就是结局!!! (The Doors) (门)

What I've done based on the links given and the incredibly detailed post of Sergio Formiggini: 根据给出的链接和Sergio Formiggini极其详细的帖子,我所做的事情:

The function: 功能:

int init(void (*notif)(const char *, const char *),
        void (*parameter1)(const char *),
        void (*parameter2)(const char *));

inside that: 在里面:

void (*funcionParametroThread)(const char *, const char *);
funcionParametroThread=&(*notif);

and to create the thread: 并创建线程:

pthread_create(&thid, &atrib_th, tcp_server, funcionParametroThread);

And once inside the function I use for the thread (tcp_server): 一旦进入函数,我就使用线程(tcp_server):

void (*funcionParametroThread)(const char *, const char *);
    funcionParametroThread=arg;
    (*funcionParametroThread)(temaRecibido,valorRecibido);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 不带参数的功能Vs带参数的功能 - function which takes no parameters Vs function which takes parameter 如何在C中打印另一个函数使用的函数的参数? - How to print a parameter of a function which is used by another function in C? 如何定义一个函数,该函数从用户那里获取输入并将其存储到一个变量中,以便在程序中进一步使用? - How to define a function that takes input from user and stores that to a variable which is further used in the program? 如何向前声明一个函数,该函数将指向函数的指针作为参数? - How to forward declare a function that takes a pointer to a function as a parameter? 为什么pthread_create函数将线程函数名作为参数而不是调用它? - why pthread_create function takes thread function name as a parameter rather than calling it? 如何使用Java Native Interface将字节数组传递给C函数,该函数将char *作为参数? - How can I use Java Native Interface to pass a byte array into a C function which takes a char* as an argument? 如何在C中将参数从线程传递给函数 - How to pass a parameter from a thread to a function in c 如何更改线程函数内的void *参数 - How to change void* parameter inside of a thread function 如何知道哪个线程正在执行 function? - How to Know which Thread is executing a function? 如何在C中创建一个带有未知类型参数的函数? - How can I create a function that takes a parameter of unknown type in C?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM