Let's utilize the design pattern like C language with OSS design_pattern_for_c!

** Introduction **

This is an introduction of the self-made library package OSS design_pattern_for_c. The wiki is here. The Doxygen code for each library API is here.

The latest version is V1.00.

(I wrote an article with the same title in v0.0.1 pre-release before. I deleted the previous article and recreated it as an official public article.)

** What is design_pattern_for_c? ** **

It is a library package that runs on Linux and allows you to take advantage of the good points of design patterns in C language.

Whenever I hear about object-oriented design and design patterns while developing a C system, I often get the impression that such ideas and expressions are often used in C as well. However, from the perspective of object-oriented languages, it may be used in a way that makes you think, "Isn't this the XXX pattern?" The reason is that ** a well-made C system uses design patterns in a way that is efficient for the C language **. ** It may be possible to say that it is not just reproducing the design, but that it is a good match between C and the design pattern **.

I think it's the same in any language. Use useful designs and tools in a language-specific way to create a better system. Let's make a good system, not whether it exactly matches those original expressions! Is the purpose.

However, C language is not an object-oriented language, so just imitating object-oriented programming just makes it more difficult to use. On the contrary, if you use C's specialty with a high degree of freedom such as void * and function pointer, you should be able to utilize a nice tool called a design pattern, although the expression method may be different. .. This library was created with that in mind.

** What can you do? ** **

Here, we will briefly introduce the support libraries in the package. Please note that it is almost like an introduction to design patterns.

Threadpool

A library that creates listening for multiple file descriptors (FDs) and wraps FD events. The library user simply registers the FD and the function pointer, and the FD is listened to by a free thread in the library. It will call the registration function according to the FD event.

Think of it as a multi-threaded event standby process for select, epoll, etc.

Japanese page OSS page

memorypool

By allocating memory for the same type (size) collectively instead of mallocing it each time, you can increase the speed of area allocation and initialization. It is effective for data that has a fixed upper limit and takes a long time to initialize.

Since the user of the library can specify the constructor in addition to the data size and number, the library will perform the initialization using the constructor when the area is secured.

There is no Japanese commentary page, but this library is an improved version of the updated wrapper on this page. OSS page

State, StateMachine

By registering the state and the function to be executed in that state, the state transition can be realized by the API of the State library. I think that it is useful for programs with complicated states and programs whose specifications are easily changed for each state.

SateMachine is a library that adds state transition events to the State library. It will be useful for realizing the state transition table.

Japanese commentary page OSS Page

Observer(Publish-Subscribe)

It is a library that realizes the following Subscriber-Publisher relationship.

  1. I have a book subscriber.
  2. Subscribers subscribe to the publications of that publisher.
  3. Later, when the publisher publishes the book, the subscriber will know that the book has been published.

⇒ Subscriber is only registered. Then you will be notified when Publisher publishes!

You can register multiple event functions in the publisher with the same ID, and you can call many event functions at once just by executing the publisher API of the publisher. Isn't it effective when there is a large amount of processing associated with the event?

Japanese commentary page OSS Page

Chain of Responsibility

This library can be used for programs that want to call a function in a string with this after calling this. If you register the functions in the library, the functions will be executed in the order of registration with one API. You can control the interruption in the middle by changing the return value of the function.

Japanese commentary page OSS page

Flyweighy, Singleton

The Flyweighy library allows users to reuse the same instance without being aware of instance creation. Instances are created and maintained in the library. By registering the equal condition as a function, it is determined whether the created instance is the same instance, and if it is the same, the already created instance is reused.

Singleton is roughly a design pattern that uses only one and the same instance, which is synonymous with always setting the Flyweighy = condition to true. So there is only one Flyweighy library.

Japanese commentary page OSS page

Prototype

It is a library that allows you to copy data in a certain state at any time by registering the data in a certain state and the copy method of the data. It is effective when you want to do troublesome things only once, such as registering and reusing after initialization of processing that is heavy in initialization.

Japanese commentary page OSS page

Builder

This is a little different from the design pattern Builder. For example, it is a useful library when you want to control multiple modules, but the initialization sequence is slightly different for each module. The library takes charge of the initial processing and makes it easy, while making it possible to use modules with slightly different initial processing.

Define the initialization API in the conf file and have each module implement the API (if you don't need it, you can leave it unimplemented). After that, if you bite the conf file and module into the library and execute the API, the library will undertake the initialization of the module.

Japanese commentary page OSS page

~~ Honestly, there is room for improvement (the sequence is good, but I can't deny the lack of consideration on how to pass the parameters). ~~ ⇒The API specifications have been reviewed.

** For example, what kind of program can you make? ** **

** HTTP server multithreading **

I used this package to make lighttpd multithreaded. https://github.com/developer-kikikaikai/lighttpd_multithread

The library usage record is roughly like this.

--Multi-thread operation for each TCP connection has been realized with thread pool and state machine. You can now handle other clients without being affected by heavy HTTP client requests. --The time to create connection information has been shortened by using the memory pool for connection information. --The response header information is reused by flyweight, and the header creation time has been shortened. --The data mainly used for reading settings has been changed to prototype registration / clone format to reduce unnecessary copying. --Observer is used for the main process and the exchange of each connection (mainly the end sequence), and the event registration on the connection side ⇒ event execution on the main side is implemented. I've cleaned up the main code a bit.

The multithreading program I made is still buggy or unfixed on the fastcgi side, but thanks to each library, multithreading is successful && It is a good match with the head family in terms of speed.

The article that summarizes the performance before supporting the following three is here. (Cgi is slow and memory usage is terrible (-_-;). This will be updated slowly)

** Multi-device LAN router **

Using the builder, I created a router that both Wifi and ethernet can use on the LAN network side. https://github.com/developer-kikikaikai/linux_router

Commentary page https://qiita.com/developer-kikikaikai/items/0d8ea1c057302ad26ea9

This uses a builder, and the library to be loaded is also managed by the json file, so it is possible to add a new module to the LAN network.

** How to use **

download

You can download it from here.

** How to use **

You can build and install by following the steps below.

  1. ./configure
  2. make
  3. sudo make install

The default is installed in / usr / local /. You can also specify the installation path with ./configure --prefix = XXX.

--You need to install autoconf, libtool, libev, libevent-dev. libev and libevent-dev can be disabled. --config may not work well due to environment dependence. If you get an "[aclocal.m4]" error, run ./autogen.sh and run 1-3.

See the wiki or the README for details.

After that, you can use it by linking the required library. Please refer to Doxygen Code for API details.

license

Except for one plugin library, it is basically MIT License.  MIT wikipedia

Only the libev plugin used by Threadpool will be GPL version 2 or any later version.

change history

I will add it when there is an API specification change or function addition to the master branch.

Change date Contents
2018/07/22 V1.00 First Edition Release
2018/07/29 ・ Builder, lower_layer_director_Synchronize construct specifications/Changed so that it can be specified asynchronously&&Input as a callback argument_Add parameter(So that memory can be released)。
・ C of various headers++Correspondence

Finally

If you have any questions or requests, please comment on this article or github issues. By the way, I forgot to update the README, and the description is not 1.00, but that is because I love you (laugh)

We would also like to thank everyone who gave us a lot of comments in the comments, Mr. Sureibu who gave us translation advice, and everyone who wrote a lot of good articles for reference. Thank you very much.

Recommended Posts

Let's utilize the design pattern like C language with OSS design_pattern_for_c!
Learn the design pattern "Singleton" with Python
Learn the design pattern "Facade" with Python
Let's develop something close to embedded with TDD ~ Design pattern ~
Writing C language with Sympy (metaprogramming)
Let's touch on the Go language
Segfault with 16 characters in C language