1 #include <iostream> 2 #include <vector> 3 4 class Bad { 5 public: 6 7 Bad(int v) { 8 data = new std::vector<int>(); 9 data->push_back(v); 10 } 11 12 // No copy constructor. Using default. 13 14 // No assignment operator. Using default. 15 16 std::vector<int> *data; 17 18 void add(int v) { 19 data->push_back(v); 20 } 21 22 void show() { 23 std::vector<int>::iterator it; 24 for (it = data->begin(); it != data->end(); ++it) { 25 std::cout << *it << " "; 26 } 27 std::cout << std::endl; 28 } 29 }; 30 31 class Good { 32 public: 33 34 Good(int v) { 35 data = new std::vector<int>(); 36 data->push_back(v); 37 } 38 39 // Copy constructor. 40 Good(const Good& rhs) { 41 42 std::cout << "Copy constructor called" << std::endl; 43 44 if (this == &rhs) { 45 // Copy to self. No action required. 46 return; 47 } 48 49 this->data = new std::vector<int>(); 50 51 // Copy elements in data manually! 52 std::vector<int>::iterator it; 53 for (it = rhs.data->begin(); it != rhs.data->end(); ++it) { 54 this->data->push_back(*it); 55 } 56 } 57 58 // Assignment operator. 59 Good& operator=(const Good& rhs) { 60 std::cout << "Assignment operator called" << std::endl; 61 62 if (&rhs == this) { 63 return *this; 64 } 65 66 // Copy elements in data manually! 67 this->data->clear(); 68 std::vector<int>::iterator it; 69 for (it = rhs.data->begin(); it != rhs.data->end(); ++it) { 70 this->data->push_back(*it); 71 } 72 73 return *this; 74 } 75 76 std::vector<int> *data; 77 78 void add(int v) { 79 data->push_back(v); 80 } 81 82 void show() { 83 std::vector<int>::iterator it; 84 for (it = data->begin(); it != data->end(); ++it) { 85 std::cout << *it << " "; 86 } 87 std::cout << std::endl; 88 } 89 }; 90 91 int main() { 92 93 std::cout << "<<<< Testing Bad. >>>>" << std::endl; 94 95 Bad b1 = Bad(10); 96 Bad b2 = b1; // Calls copy constructor. 97 98 b2.show(); // Prints 10 . 99 b1.add(20); 100 b2.show(); // Prints 10 20 (!) 101 102 std::cout << "<<<< Testing Good. >>>>" << std::endl; 103 104 Good g1 = Good(10); 105 Good g2 = g1; // Calls copy constructor. 106 107 g2.show(); // Prints 10 . 108 g1.add(20); 109 g2.show(); // Prints 10 . :) 110 111 g2 = g1; // Calls assignment operator. 112 g2.show(); // Prints 10 20 . :) 113 }
Programmer's Diary
Tuesday, June 13, 2017
Copy constructor or assignment operator
Using default copy constructor or assignment operator may cause misleading behavior as following code I wrote.
Thursday, March 5, 2015
MathJax for writing an equation on web page.
<pre>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<p>$$ Equation here $$</p>
Then will look like,
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<p>$$ Equation here $$</p>
Then will look like,
$$ \textit{h}_{\theta }\left ( \textit{x} \right ) = \theta _{0} + \theta _{1} \textit{x} _{1} + \cdots + \theta _{n} \textit{x} _{n} $$
Wednesday, July 30, 2014
Justify alignment
I didn't know that it's called 'Justify alignment'. I decided to implement with C#. Process is simple. Get text and line width, split text into words, make them group of words for each line, print line after padding it with seperator so that start and end of a line will be characters as possible as it can.
Then the output is,
namespace Justify { class Program { /// <summary> /// Does justify alignment for given text. /// </summary> /// <param name="text">string input</param> /// <param name="lineWidth">Line width</param> /// <returns>List of lines aligned with justify option.</returns> static List<string> Justify(string text, int lineWidth) { var output = new List<string>(); // 1. Split text into list of words. List<List<string>> wordLists = getWords(text, lineWidth); // 2. Do justify align per each line. foreach (var list in wordLists) { output.Add(padding(list, lineWidth)); } return output; } static private List<List<string>> getWords(string text, int lineWidth) { var output = new List<List<string>>(); // Split whole text into words. string[] words = text.Split(new char[] { ' ' }); // current width of words with seperator(' ') included. int length = 0; // List of words to be in a line. var wordList = new List<string>(); for (int i = 0; i < words.Length; ++i) { // If length of current word is the same or longer than line width, if (length == 0 && words[i].Length >= lineWidth) { // Cut it with line length and put it into word list. wordList.Add(words[i].Substring(0, lineWidth)); // If a word is longer than line width, if (words[i].Length > lineWidth) { // Take the rest of the word and put it into word list back // so the rest part would be in next line. words[i] = words[i].Substring(lineWidth, words[i].Length - lineWidth); i--; } // Put a line into output list. output.Add(wordList); wordList = new List<string>(); } // If current line can't contain current word, // 1 for seperator ' ' else if (length + 1 + words[i].Length > lineWidth) { // pub a line into output list. output.Add(wordList); // Prepare a new line and reset counter. wordList = new List<string>(); length = 0; i--; } // Else, put a word and increase counter. else { wordList.Add(words[i]); length += words[i].Length + 1; } } return output; } // This does justify. For example, if words ["How", "are", "you"] // and line width 15 is given, output will be // 123456789012345 <- index // How are you static private string padding(List<string> wordList, int lineWidth) { // Return empty string if empty list is given. if (wordList.Count == 0) return string.Empty; int i = 0; int length = 0; // Length is sum of all words length in the list. foreach (var word in wordList) { length += word.Length; } // Here we append seperator to all words in the list // until length is as same as lineWidth. while (length < lineWidth) { if (i == 0 || i != wordList.Count - 1) { wordList[i] = wordList[i] + " "; length++; } i = (i + 1) % wordList.Count; } return string.Join<string>("", wordList); } static void Main(string[] args) { string text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; var output = Justify(text, 30); foreach (var line in output) Console.WriteLine(line); } } }
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
Wednesday, June 18, 2014
Producer and multi-consumer sample code using C# (2)
If we use concurrent queue, we can just throw away all the complicated lock mechanism or concurrency and focus on the logic itself. Not sure if c# concurrent queue implemented it with lock free mechanism but producer-consumer code can be written in less than 100 lines.
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SimpleProducerConsumer { class Producer { private ConcurrentQueue<int> q; public Producer(ConcurrentQueue<int> q) { this.q = q; } public void Run() { while (true) { int w; Console.Write("Gimme a work: "); w = Convert.ToInt32(Console.ReadLine()); this.q.Enqueue(w); Console.WriteLine(); } } } class Consumer { private ConcurrentQueue<int> q; public Consumer(ConcurrentQueue<int> q) { this.q = q; } public void Run() { while (true) { int w = -1; if (q.TryDequeue(out w)) { Console.WriteLine("\nExtracted {0} from the queue and processed", w); } Thread.Sleep(1000); } } } class Program { static void Main(string[] args) { var q = new ConcurrentQueue<int>(); var producer = new Producer(q); var consumer = new Consumer(q); Thread tProducer = new Thread(producer.Run); Thread tConsumer = new Thread(consumer.Run); tConsumer.Start(); tProducer.Start(); } } }
Saturday, January 18, 2014
C# Interlocked
Like CLI, STI inline assembly in C or like scope lock in C++, there is interlocked class for atomic operation in C#. Easy and good to make code look clean.
Tuesday, July 16, 2013
Producer and multi-consumer sample code using C#
As a practice of multi-thread code using C#, I wrote a sample code of producer and consumer model. I used custom threadpool so that workers never end until they receive end signal and check work queue timely.
Producer and consumer model is simple. There is a task queue. Producer puts tasks into the queue. And consumer process a task when it finds in the queue. The code has one producer and multiple consumers.
I used basic lock mechanism. Because there's no Monitor()/Pulse() here, producer and consumer should check the queue timely with Sleep() instead.
Producer and consumer model is simple. There is a task queue. Producer puts tasks into the queue. And consumer process a task when it finds in the queue. The code has one producer and multiple consumers.
I used basic lock mechanism. Because there's no Monitor()/Pulse() here, producer and consumer should check the queue timely with Sleep() instead.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // For producer and consumer threads. using System.Threading; namespace ProConSample { /** * In this sample, 2,000 tasks will be generated by a producer * and 10 consumers(workers) will process them. */ class Conf { public const int numTasks = 2000; public const int numWorkers = 10; public const int maxTaskValue = 100; public const bool debugMode = true; } class Util { public static void DEBUG(string format, params object[] args) { if (Conf.debugMode) { Console.WriteLine(format, args); } } } /** * WorkQueue has a lock so that only one thread at a time can * access to it. */ class WorkQueue { public readonly object aLock = new object(); private Queue<int> _queue; public WorkQueue() { _queue = new Queue<int>(); } public void Enqueue(int v) { // TODO: exception handling for _queue.Length reaches Max value. _queue.Enqueue(v); } public int Dequeue() { // TODO: exception handling for _queue is empty return _queue.Dequeue(); } public int Length { get { return _queue.Count; } } } /** * Producer puts tasks into workQueue. */ class Producer { private Random _random = new Random(); private WorkQueue _queue; private const int _sleepInterval = 1; public Producer(WorkQueue q) { _queue = q; } public void Start() { Util.DEBUG("Producer started"); for (int i = 0; i < Conf.numTasks; ++i) { int v = _random.Next(Conf.maxTaskValue); lock(_queue.aLock) { _queue.Enqueue(v); } Util.DEBUG("[Producer] Enqueued {0}", v); /** * If you don't sleep at all, this function will occupy * a core till it ends. If this happens in a single core * machine, consumers can not start its routine until * the producer ends its work. */ Thread.Sleep(_sleepInterval); } Util.DEBUG("Producer ended"); } } /** * Consumers check workQueue. If there's a task, consumer will * dequeue a task and will process with it. */ class Consumer { private WorkQueue _queue; private int _taskLeft; public int NumTaskDone { get; set; } public bool EvEnd { get; set; } private const int _sleepInterval = 1; public Consumer(WorkQueue q) { _queue = q; _taskLeft = 0; EvEnd = false; NumTaskDone = 0; } public void Start() { Util.DEBUG("Consumer started"); while (true) { int v = 0; // Check if we have a task to do lock (_queue.aLock) { _taskLeft = _queue.Length; if (_taskLeft > 0) { v = _queue.Dequeue(); } } // Process a task. if (_taskLeft > 0) { Util.DEBUG("[Worker] Dequeued {0}", v); NumTaskDone++; } /** * Ending condition: * No work left in the queue and ending event received. */ if (EvEnd && _taskLeft == 0) { break; } /** * If consumer doesn't sleep here, it will hold a core. * If consumers hold all cores so that the producer has * no chance to get core to enqueue, deadlock occurs. */ Thread.Sleep(_sleepInterval); } Util.DEBUG("Consumer ended: processed {0} tasks", NumTaskDone); } } /** * ThreadPool which contains consumers and threads in the list. */ class ThreadPool { Consumer[] consumers = new Consumer[Conf.numWorkers]; Thread[] threads = new Thread[Conf.numWorkers]; public ThreadPool(WorkQueue q) { for (int i = 0; i < Conf.numWorkers; ++i) { consumers[i] = new Consumer(q); threads[i] = new Thread(new ThreadStart( consumers[i].Start )); } } public void Start() { for (int i = 0; i < Conf.numWorkers; ++i) { threads[i].Start(); } } public void SetEndEvent() { for (int i = 0; i < Conf.numWorkers; ++i) { consumers[i].EvEnd = true; } } public void Join() { for (int i = 0; i < Conf.numWorkers; ++i) { threads[i].Join(); } } } class ProCon { static void Main(string[] args) { // Create a work queue. WorkQueue workQueue = new WorkQueue(); // Create a producer. Producer producer = new Producer(workQueue); Thread tProducer = new Thread(new ThreadStart(producer.Start)); // Create consumers. ThreadPool tConsumers = new ThreadPool(workQueue); // Start producer and consumers tProducer.Start(); tConsumers.Start(); // If producing ends, set an end event signal. tProducer.Join(); tConsumers.SetEndEvent(); /** * TODO: Is there any method to wait all thread in a specific * list ended? */ // Join consumers thread ended tConsumers.Join(); } } }
Wednesday, June 12, 2013
Using libssh2 on multithread code.
Day1.
I have a daemon running on CentOS4.3. By the way, an operator told me that the server it resides should be moved to the other rack. So I decided to move and upgrade OS version to CentOS6.3 with gcc-4.4.6 during migration. I moved and compiled. But it stopped after several minutes. The daemon spawns many threads and each thread has socket connected via boost::asio. Each thread passes connected socket to libssh2_session_handshake() for ssh connection. Libssh2 library is used here. It uses libgcrypt library to generate 16 bytes of random numbers. However, gdb didn't show call stack when it goes into library routine(showed function name like ???() ). To know where it stops, I downloaded each libraries(libssh2, libgcrypt, libgpg-error) and compiled them again. Gdb finally showed that libgcrypt tries to attain mutex lock to access random pool for generating random number, it stops because it designed to fail to get mutex lock and assert. It works well on single thread environment. This isn't typical way to use libssh2 library. No helpful answer found at Google... TT.
Day2.
After doing more googling, bingging I found interesting information. Acturally both libssh2 and libgcrypt are designed for multithread environment. There was nothing to do for libssh2 to run it on MT-ed code. But something should have been done for libgcrypto. Because it doesn't know which thread mechanism is used in the host, it implemented two types of structures and functions for mutex as a macro. One for pthread and the other for pth. So the application code that I'm managing should select which macro to be used by adding following lines before it forks thread(pthread selected).
#include <gcrypt.h>
GCRY_THREAD_OPTION_PTHREAD_IMPL;
And it also should call gcry_control() so that the library assign callbacks to each functions related to mutex it uses like below.
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
Several day has passed, and the server works well up to now. Hooray! :)
Subscribe to:
Posts (Atom)