Is there an easier way to create a static library?

I have this static C library in which I need to run multithreading (threads do not interact with each other, I just need several of them at the same time to speed things up). Moreover, I wrapped the c library in the C ++ cli library, which is then used by the main C # application.

Since the static library does not respond well to several threads passing through it (which is not in my control, I do not have a source for its dependencies), I resorted to copying (with slight variations) the whole many times and putting another shell between the C ++ library ci (and its copies) and a C # application that emulates copies of up to 8 instances of an object. It works, but its rather rude and cumbersome to make any changes to the functionality of the library.

Does anyone know an easier way to achieve the same effect? It’s best to guess that I have some kind of static part of the memory where there is a conflict between several threads working in the same library, is there a way to force all static variables to be specific threads? (without the ability to go to them add a stream declspec).

+5
source share
2 answers

Since you are using your C # library from C # through the C ++ / CLI layer, it looks like your link relationships look like this:

(C # application) - dynamic β†’ (C ++ / CLI DLL) - static β†’ (C library)

Background:

Since you stated that you have no way to modify or otherwise commit your C library, you really have no way to solve the thread safety problem without duplicating the C library in memory anyway, which will allow you to effectively duplicate global data that / certainly causes thread conflicts.

No matter how you look at it, your only way to solve this problem is to duplicate the DLL (your current approach) will require you to know how many duplicates you need in advance, and each of these DLLs will be slightly different from the exported ones (for example, each the class or namespace name will need another C ++ / CLI class class). As you stated, this is really rude (and I will add it is difficult to manage and impossible to scale).

Decision:

I think your best and cleaner option is with EXE duplication. To do this, you insert a new EXE in front of your C ++ / CLI DLL and dynamically link it using the IPC mechanism of your choice ( IPC Mechanisms in C # - Usage and Best Practices ). Lets call this exe your exe service. If you create an instance of the EXE service for each thread in the main C # application, then each EXE service will load its own copy of the C ++ / CLI DLL and, therefore, its own version of the C library. This means that each thread works with a copy of the library C through the exe service.

Here's what your link relationships look like:

(C# application)--IPC-->(C# service EXE)--dynamic-->(C++/CLI DLL)--static-->(C library) 

In the physical conditions of the file, it will look like this:

 MainApp.exe--IPC-->ServiceApp.exe--dynamic-->CppCliWrapper.dll 

To optimize this solution, you should try to avoid creating / deleting heavy threads, as this is related to creating / deleting the EXE service. For example, you can pre-allocate X threads at startup and use these threads throughout the entire application life cycle. You might also consider performing operations to optimize IPC costs. It all depends on the needs and details of your application.

To do this even more, you can potentially scale this solution across all computers if you choose an IPC mechanism that works over TCP / IP. Then you can process your operations on as many machines as you want. This is how many companies turn DLLs into horizontally scalable services. It's not as simple as it sounds, but food, though, if you need to scale this thing.

+1
source

The problem is that the library is not repetitive. If you have access to the source code of the library, it is best to search all global variables and make them stream local. This can be done using the thread_local keyword in C ++ 11 or using the __thread keyword if compiled with gcc / g ++.

This ensures that each thread will use a different copy of each global variable.

0
source

Source: https://habr.com/ru/post/1201883/


All Articles