【问题标题】:If main is a thread as well in c, why doesn't it run with other threads如果main也是c中的一个线程,为什么它不与其他线程一起运行
【发布时间】:2020-03-05 07:07:56
【问题描述】:

我读到 main() 本身就是单线程,所以当我像这样在我的程序中创建 2 个线程时;

#include<stdio.h>
#include<pthread.h>
#include<windows.h>

void* counting(void * arg){
    int i = 0;
    for(i; i < 50; i++){
        printf("counting ... \n");
        Sleep(100);

    }
}

void* waiting(void * arg){
    int i = 0;
    for(i; i < 50; i++){
        printf("waiting ... \n");
        Sleep(100);
    }
}

int main(){
    pthread_t thread1;
    pthread_t thread2;
    pthread_create(&thread1, NULL, counting, NULL);
    pthread_create(&thread2, NULL, waiting, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    int i = 0;
    for(i; i < 50; i++){
        printf("maining ... \n");
        Sleep(1000);
    }


}

在这种情况下,main 真的是一个线程吗? 在那种情况下,如果 main 处于睡眠状态一段时间,main 不应该将 CPU 交给其他线程吗? main 是线程本身吗?我在这里有点困惑。 主线程执行是否有特定顺序?

【问题讨论】:

  • pthread_join 作为代码的最后一行。现在main 挂在他们身上。
  • 想想pthread_join 的真正作用...花点时间阅读它的手册页。
  • 如果我更改 pthread_join 并使其成为最后一条语句。它仍然先打印线程,最后打印主线程
  • main 函数中的循环大约需要 50 秒(50 乘以一秒的睡眠),但线程循环只需大约 5 秒(50 乘以 @987654328 @第二次睡眠)。这意味着两个创建的线程将比“主”线程更快地完成很多。但是应该有一些(一些)"maining ..." 输出混合在创建线程的输出中。您需要将输出向上滚动到顶部才能看到它。
  • 我得到了一个新答案,上面写着“main 不是线程而是函数”?这是正确的@Someprogrammerdude

标签: c multithreading pthreads


【解决方案1】:
 pthread_join(thread1, NULL);
 pthread_join(thread2, NULL);

您要求线程等到thread1 终止,然后等到thread2 终止,这就是它的作用。

【讨论】:

    【解决方案2】:

    我读到 main() 本身就是单线程

    不,你误会了。每个 C 程序都有一个名为main()函数。程序的 C 语言语义从该函数的初始入口开始。从这个意义上说,尤其是当您提供括号时,main() 是一个函数,而不是一个线程。

    然而,每个进程也有一个主线程,它有一些区别于其他线程的属性。那是最初唯一的线程,所以它是执行初始进入main() 函数的线程。但它也是运行由main() 和这些函数调用的所有 C 函数的线程,etc.,所以一般来说,它并不特定于只运行直接出现在main() 的主体,如果这就是您所说的“main() 本身就是一个线程”的话。

    ,所以当我像这样在我的程序中创建 2 个线程时; [...] 在这种情况下, main 真的是一个线程吗?

    在这种情况下确实有一个主线程,与它启动的两个附加线程分开。

    那么如果main在sleep一段时间,main不应该把CPU交给其他线程吗?

    如果主线程在其他两个线程中的任何一个还活着的情况下处于休眠状态,那么是的,人们会期望其他两个线程中的一个或两个获得(更多)CPU 时间。从某种意义上说,这正是发生的事情:主线程依次在每个其他线程上调用pthread_join(),这导致它等待(有些人会说“睡眠”),直到这些线程在它继续之前终止。在等待时,它不会与其他线程争夺 CPU 时间,因为这几乎就是“等待”的意思。但是当主线程到达程序中的Sleep() 调用时,其他线程已经终止并加入,因为这就是pthread_join() 所做的。它们不再存在,因此它们自然不会在Sleep() 期间运行。

    这里是主线程本身吗?

    有一个主线程,是的,它是您的特定进程中唯一执行函数main() 中任何代码的主线程。除了在某个线程或其他线程中之外,什么都不会被执行。

    我在这里有点困惑。主线程执行是否有特定顺序?

    如前所述,主线程最初是唯一的线程。许多程序从来没有超过那个。主线程以外的线程仅由主线程或已创建的另一个线程创建。当然,线程在创建之前不能运行,根据定义,在它们终止之后也不能运行。线程彼此独立执行,通常没有任何预定义的顺序,除非通过诸如互斥锁之类的同步对象、通过诸如pthread_join() 之类的专用函数或通过诸如管道之类的各种I/O 对象上的协作操作来显式地建立线程。

    【讨论】:

      【解决方案3】:

      main() 不是一个线程而是一个函数,所以这里对您最初的声明明确表示“不”。但是,如果您阅读一些关于什么是线程的定义,您会发现它是可以调度的,即代码的持续执行。此外,如果没有“持续执行代码”,正在运行的程序将无法实际执行任何操作,例如main() 作为第一个入口点。所以,毫无疑问,程序执行的每一个代码都是由线程执行的,没有例外。

      顺便说一句:您可以检索当前线程的线程 ID。尝试从main() 运行它。它会起作用并为您提供一个值,以将此调用与来自其他线程的调用区分开来。

      【讨论】:

      • 对,main() 是一个函数。它是进程的第一个线程调用的第一个函数。
      • @WaqarHaider,每个 C 程序都从一个线程开始,几乎一个线程做的第一件事就是调用main(...)。这就是为什么人们经常称其为“主线程”。
      猜你喜欢
      • 2022-06-11
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      • 1970-01-01
      相关资源
      最近更新 更多