简体   繁体   English

多线程中的执行流程是什么?

[英]What is the flow of execution in Multi-threading?

I am facing a problem in multi-threading. 我在多线程方面遇到了问题。 Please consider the following code: 请考虑以下代码:

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

void* functionA(void*);
void* functionB(void*);


int main()
{   
    pthread_t tid[2];
    pthread_attr_t arg;

    for(int i = 0; i<2; ++i)
    {
        pthread_attr_init(&arg);

        if(i == 0)
        {
            int x = 0;  
            pthread_create(&tid[i], &arg, functionA, (void*)&x);
        }

        else if(i == 1)
        {
            int x = 6;  
            pthread_create(&tid[i], &arg, functionB, (void*)&x);
        }
    }

 // wait for both threads to finish execution...    
 pthread_join(tid[0], NULL);
 pthread_join(tid[1], NULL);

 return 0;
 }


//.........................DEFINATIONS........................

void* functionA(void* x)
{
    int Index = *((int*)x);
    printf("First: %d\n",Index);    //..................... LINE M
}


void* functionB(void* x)
{
    int Index = *((int*)x);
    printf("Second: %d\n",Index);   //....................... LINE N
}

Now I believe that functionA will start its execution first, because ofcourse thread for functionA will be created first in for loop, so according to me the output should be: 现在我相信functionA将首先开始执行,因为函数A的求助线程将首先在for循环中创建,所以根据我的输出应该是:

  First: 0                         (from Line M)
  Second: 6                        (from Line N)

but the actual output is, 但实际输出是,

  Second: 6
  First: 6

Now I am really surprised to see this, and I don't know what's happening. 现在我很惊讶地看到这一点,我不知道发生了什么。 Not only secondFunction start its execution first, but also both the functions are showing same value ie 6, and it doesn't make sense to me. 不仅secondFunction首先开始执行,而且两个函数都显示相同的值,即6,这对我来说没有意义。 Can anyone please Explain me what is going on here???? 任何人都可以请你解释一下这里发生了什么???? Thanks in advance... 提前致谢...

two things 两件事情

1) Here x variable scope is limited to that if block only. 1)这里x变量范围仅限于块if。 so in your thread function when you are accessing that pointer its scope is gone So you are accessing illegal memory in thread function which is wrong and it will create undefined behavior. 所以在您的线程函数中,当您访问该指针时,其范围已经消失所以您正在访问线程函数中的非法内存,这是错误的,它将创建未定义的行为。

In response to your one comment 回应你的一条评论

so is there any way that instead of variable, I can directly send a constant number, for example pthread_create(&tid[i], &arg, functionA, 6) ?? 那么有没有办法代替变量,我可以直接发送一个常数,例如pthread_create(&tid [i],&arg,functionA,6)??

POSIX threads is a C API. POSIX线程是一个C API。 C does not provide language facilities like copy constructors and so it is not possible to copy any object by value. C不提供像复制构造函数这样的语言工具,因此无法按值复制任何对象。

You need to always pass something by pointers only. 你需要总是只通过指针传递一些东西。

2) The priority of execuattion of threads is totaly OS and schedular dependednd you can not assume on the sequence of those threads. 2)执行线程的优先级是完全操作系统和调度程序依赖,你不能假设这些线程的序列。

Still you want some synchronisation between threads then use mutex, conditional variable etc.. 你还想在线程之间进行一些同步,然后使用互斥,条件变量等。

You're passing pointers to short-lived local variables into the threads, causing undefined behavior as soon as those scopes exit. 您将指向短期局部变量的指针传递到线程中,一旦这些范围退出就会导致未定义的行为。 Probably both threads see the same address to x . 可能两个线程都看到x的相同地址。

The most obvious fix would be to use a higher scope for the variables, and have an array with an integer per thread: 最明显的解决方法是为变量使用更高的范围,并且每个线程都有一个整数数组:

 pthread_t tid[2];
 pthread_attr_t arg;
 int x[2] = { 0, 6 };
 void * (*func[])(void *) = { functionA, functionB };

 for(int i = 0; i < 2; ++i)
 {
     pthread_attr_init(&arg);
     pthread_create(&tid[i], &arg, func[i], &x[i]);
 }

 // wait for both threads to finish execution...    
 pthread_join(tid[0], NULL);
 pthread_join(tid[1], NULL);

This works since the x array will live past the calls to pthread_join() . 这是有效的,因为x数组将通过对pthread_join()的调用。 Also no need to cast the pointer, int * converts automatically to void * in C. 也不需要int *转换指针, int *自动转换为C中的void *

Also your assumption about the order in which the threads start is false, there are no such guarantees. 关于线程开始顺序的假设也是假的,没有这样的保证。

There is no guarantee in which order they will run. 无法保证他们将以何种顺序运行。 When creating the thread the operating system's scheduler will register the new thread and run it whenever it has time. 创建线程时,操作系统的调度程序将注册新线程并在有时间时运行它。 Based on priority and other hings on the system it might pick them in any order, ie interrupt the main thread and start one of the others, or run the main thread till the join and then start any other thread. 基于系统上的优先级和其他hings,它可以按任何顺序选择它们,即中断主线程并启动其他线程,或运行主线程直到连接,然后启动任何其他线程。

Likely you're testing on a multi-core system. 可能你正在测试多核系统。 Then those might even run in parallel at the same time, but for some reason one or the other might be faster (maybe data from the second is in a cache whereas the first has to fetch data from memory?) 那些甚至可能同时并行运行,但由于某种原因,一个或另一个可能更快(可能来自第二个的数据在缓存中,而第一个必须从内存中获取数据?)

Long story short: There is no guarantee whatsoever. 长话短说:没有任何保证。

If you need a specific order you can use locks (ie mutexes) to enforce synchronisation or you might set priority (see setpriority()) or enforce real-time scheduling (sched_setscheduler()) but then you really should understand your operating system. 如果您需要特定订单,您可以使用锁(即互斥锁)来强制执行同步,或者您可以设置优先级(请参阅setpriority())或强制实时调度(sched_setscheduler()),但您真的应该了解您的操作系统。

I believe that functionA will start its execution first, because ofcourse thread for functionA will be created first in for loop 我相信functionA将首先开始执行,因为forA的forcourse线程将首先在for循环中创建

This assumption is not correct that is dependent on thread scheduling that control by OS. 这种假设不正确,这取决于OS控制的线程调度。

If you want see correct output declare two variable in main() function scope (before for loop) 如果要查看正确的输出,请在main()函数范围内声明两个变量(在for循环之前)

int x = 0;  
int y = 6;  

and also make change in 并且还要改变

pthread_create(&tid[i], &arg, functionA, (void*)&x);
 pthread_create(&tid[i], &arg, functionB, (void*)&y);

By doing this you get at least correct output. 通过这样做,您至少可以获得正确的输出。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM