简体   繁体   English

从多个线程在C文件中调用函数

[英]Calling a function in C file from multiple threads

I am working with a code base with some .C files and .CPP files. 我正在使用包含某些.C文件和.CPP文件的代码库。

The multiple threads in the system calls some functions in C files as the one given below. 系统中的多个线程调用C文件中的某些函数,如下所示。

void CalculateCrc(PWORD pwCRC, PBYTE pbyBuffer, DWORD dwBufferLen)
{
    WORD wFCS = 0xffff;

    ASSERT(pbyBuffer);
    ASSERT(pwCRC);
    while(dwBufferLen--)
    {
        wFCS = (WORD)(wFCS >> 8) ^ tbl_FCS[(wFCS ^ *pbyBuffer++) & 0xff];
    }
    wFCS ^= 0xffff; // complement
    *pwCRC = wFCS;
}

For each calling thread will there be copies of arguments[pwCRC, pbyBuffer, dwBufferLen] and non-static data members of function [WORD wFCS], or will there be only a single set of data shared by all threads that will result in data corruption and make the calls from multiple threads unsafe? 对于每个调用线程,将存在参数[pwCRC,pbyBuffer,dwBufferLen]和函数[WORD wFCS]的非静态数据成员的副本,或者所有线程仅共享一组数据,这将导致数据损坏并使来自多个线程的调用不安全?

I am not a native English speaker. 我不是英语母语人士。 Forgive me if the question is not asked in a clear manner. 如果问题不清楚,请原谅我。

Thanks for your time. 谢谢你的时间。

I believe each thread will have its own stack, which is a copy of the spawning process' stack ( I hope I am technically correct on this one ). 我相信每个线程都会有自己的堆栈,该堆栈是生成进程堆栈的副本( 我希望从技术上讲这是正确的 )。 They do share address space and heap though. 他们确实共享地址空间和堆。

So anything that existed before spawn will be shared. 因此,在生成之前存在的任何东西都将被共享。 Anything created after is thread-local. 之后创建的任何内容都是线程本地的。 And since everything is passed by value, and data member is non-static, it will be created thread-local. 而且由于所有内容都是按值传递的,并且数据成员是非静态的,因此它将在线程本地创建。

Your function per-se is safe. 您的功能本身很安全。 However, since you work with pointers, you need to take care that two threads do not work over the same memory area. 但是,由于使用了指针,因此需要注意两个线程不能在同一内存区域上工作。 The variables are safe, the memory is not. 变量是安全的,内存不是。

will there be copies of arguments[pwCRC, pbyBuffer, dwBufferLen] 是否会有参数的副本[pwCRC,pbyBuffer,dwBufferLen]

In C, the arguments are passed by value, so for each call from different threads these will have different copied. 在C语言中,参数是按值传递的,因此对于来自不同线程的每个调用,它们将复制不同的内容。 However, if the passed variables are global/shared by the threads then all such threads will pass the same variables. 但是,如果传递的变量是线程全局的/共享的,则所有此类线程将传递相同的变量。

In your case PWORD pwCRC, PBYTE pbyBuffer are pointers. 在您的情况下, PWORD pwCRC, PBYTE pbyBuffer是指针。 If these are shared between the threads then also, your function is not thread-safe. 如果它们在线程之间共享,那么您的函数也不是线程安全的。 As multiple threads may try to change the value pointed by these pointers. 由于多个线程可能会尝试更改这些指针所指向的值。

non-static data members of function [WORD wFCS] 函数[WORD wFCS]的非静态数据成员

Yes, there will be copy for each function call. 是的,每个函数调用都将有一个副本。

The function will have its own copy of pwCRC and dwBufferLen BUT NOT pbyBuffer because you are passing it as a pointer. 该函数将拥有其自己的pwCRC和dwBufferLen副本,但不是pbyBuffer,因为您将其作为指针传递。

I give two solutions: 我给出两个解决方案:

A. ensure that all threads only have read (or no) access to pbyBuffer while this function is called; A.确保在调用此函数时,所有线程仅对pbyBuffer具有读取(或没有)访问权限; or (if the data is rather small 或(如果数据很小

You could do this by making a copy. 您可以通过制作副本来做到这一点。

B. Pass the buffer by value. B.按值传递缓冲区。 you can do this by using a structure 你可以通过使用结构来做到这一点

struct buffer { char buffer [LEN] ; 结构缓冲区{char buffer [LEN]; } }

This only works if the buffer is small. 这仅在缓冲区较小时起作用。 If I remember correctly, the C++ standard limits the size of the call stack as a concession to the VAX architecture. 如果我没记错的话,C ++标准会限制调用堆栈的大小,这是对VAX架构的一种让步。 Your compiler might exceed the limits of the standard. 您的编译器可能超出了标准的限制。 Even so, it is not a good idea to kill the stack with large arguments. 即使这样,用大参数杀死堆栈也不是一个好主意。

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

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