是否可以在多个文件中创建要在主文件中执行的线程?

时间:2018-06-10 03:59:59

标签: c linux multithreading parallel-processing pthreads

我有以下结构想要在2个独立的线程上与分类器(无限循环)和网络器(无限循环)进行交互。线程在它们各自的文件而不是主文件中生成。这有什么问题吗?

的main.c

int main(void {
   network();
   sorter();
}

sort.c //创建随机数组,然后在连续的while循环(永不结束)

中对它们进行排序
void sorter() {
    int r1 = pthread_create(&thread1, NULL, (void *) &sorter, NULL);
    pthread_join(thread1, NULL);
}

int* getArray() { ... }
int getElement() { ... }

network.c

void network() {
   int r2 = pthread_create(&thread2, NULL, (void *) &startNetwork, NULL);
   pthread_join(thread2, NULL);
}

void startNetwork() {
  int sockfd, portno, optval, n;
  socklen_t adSize;
  struct sockaddr_in servAd, clientAd;
  ...
  while(1) { 
    //receive packet 
   int *arr = getArray();
   // send packets
   // or receive packet that has a command to get array 
  }

}

是否可以让线程结构如此?我的主文件是否会冻结,因为主文件中没有创建线程?有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

sorter()的主要问题是(1)它在线程函数返回之前不会返回,(2)线程函数是sorter(),所以你有一个无限循环。这可能是尝试将代码抽象到问题中的问题。有一些细节可以解决,比如函数的类型等等。

network()的问题可能相似或不同;你没有显示你从main()调用的函数,因此不清楚你的意图。 networker()中的代码不好;它使pthread_create()调用带有错误签名的函数 - 线程函数应该具有签名void *function(void *arg);

但是,通常,在不同源文件的代码中启动不同的线程没有问题。如果线程没有分离 - 如果你要加入它们 - 那么你需要使pthread_t初始化为pthread_create()可用于管理加入的代码 - 可能是因为它们是在全局变量或全局数组的一部分中,或者可能是因为您提供对存储在单独源文件中的私有数据的功能访问。

所以,你可能有:

<强> network.c

static pthread_t thread2;

static void *network_thread(void *arg);

void network(void)
{
    if (pthread_create(&thread2, NULL, network_thread, NULL) != 0)
        …handle error…
}

void network_join(void)
{
    void *vp = 0;
    if (pthread_join(&thread2, &vp) != 0)
        …report error…
    …maybe use the return value in vp…
}

<强> sorter.c

static pthread_t thread1;
static void *sorter_thread(void *arg);

void sorter(void)
{
    if (pthread_create(&thread1, NULL, sorter_thread, NULL) != 0)
        …handle error…
}

void sorter_join(void)
{
    void *vp = 0;
    if (pthread_join(&thread1, &vp) != 0)
        …handle error…
    …maybe use value in vp…
}

<强> main.c

#include "sorter.h"
#include "network.h"

int main(void)
{
    network();
    sorter();
    network_join();
    sorter_join();
    return 0;
}

您可能会对network_join()sorter_join()构建检查,这样如果您尚未调用network()sorter(),则代码将不会尝试加入无效的线程。

答案 1 :(得分:0)

  

这有什么问题吗?

看起来你可能不明白pthread_join(thread1)的作用。除了等待thread1完成之外,它确实没有。但是你说网络线程和分拣机线程都要永远运行,所以这将是一个漫长的等待:

为了将来参考,pthread_join()应该像这样使用:

pthread_create(&thread1, attrs, f, arg);
doSomethingElse(...);
pthread_join(thread1, NULL);
doOtherStuff(...);

原始线程启动新线程,然后在新线程调用f(arg)时执行其他操作。然后,在f(arg)调用和doSomethingElse(...)调用都完成后,原始主题会转到doOtherStuff(...)