Skip to content

Instantly share code, notes, and snippets.

@baoilleach
Last active February 21, 2017 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baoilleach/1a7e517798804bdd96b3e9b4927092ce to your computer and use it in GitHub Desktop.
Save baoilleach/1a7e517798804bdd96b3e9b4927092ce to your computer and use it in GitHub Desktop.
Test multithreaded Open Babel application
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <process.h>
#ifdef WIN32
#define USING_OBDLL
#endif
#include <openbabel/babelconfig.h>
#include <openbabel/obconversion.h>
#include <openbabel/mol.h>
#include <openbabel/locale.h>
#define MAX_THREADS 2
HANDLE hScreenMutex; // "Screen update" mutex
int ThreadNr; // Number of threads started
typedef std::vector<std::string> SmiData;
struct ThreadData {
ThreadData(unsigned int _id, SmiData *_smis) : id(_id), smis(_smis) {};
~ThreadData() {
delete smis;
}
unsigned int id;
SmiData* smis;
};
using namespace OpenBabel;
void DoSearch(void* threadData)
{
ThreadData* tdata = (ThreadData*)threadData;
WaitForSingleObject(hScreenMutex, INFINITE);
printf("Starting thread %d\n", tdata->id);
ReleaseMutex(hScreenMutex);
OBConversion conv;
conv.SetInFormat("smi");
for (int i = 0; i < tdata->smis->size(); ++i) {
OBMol mol;
conv.ReadString(&mol, (*tdata->smis)[i].c_str());
std::string noel = conv.WriteString(&mol);
}
WaitForSingleObject(hScreenMutex, INFINITE);
printf("Finishing thread %d\n", tdata->id);
ReleaseMutex(hScreenMutex);
delete tdata;
InterlockedDecrement((LONG*)&ThreadNr);
}
void StartThreads(void) // Dispatch and count threads.
{
obErrorLog.StopLogging(); // not thread-safe
OBConversion conv;
conv.SetInFormat("smi"); // loading of plugins not thread-safe so do it here
OBMol mol;
conv.ReadString(&mol, "C"); // Init() of global typers not thread-safe so do it here
obLocale.SetLocale(); // Prevent Open Babel later get/setting the locale by doing it here
const unsigned int chunksize = 10;
std::ifstream inp("C:\\Tools\\openbabel\\mySmilesValence\\build\\chembl_20_subset.smi");
std::string smi;
unsigned int i = 0;
unsigned int threadid = 0;
SmiData* data = new SmiData(chunksize);
while (std::getline(inp, smi))
{
(*data)[i] = smi;
if (i == chunksize - 1) {
// block on thread finishing
while (ThreadNr >= MAX_THREADS) {
Sleep(50);
}
InterlockedIncrement((LONG*)&ThreadNr);
ThreadData *td = new ThreadData(threadid++, data);
_beginthread(DoSearch, 0, td);
i = 0;
data = new SmiData(chunksize);
}
else
i++;
}
while (ThreadNr > 0) {
Sleep(250);
}
obLocale.RestoreLocale(); // Undo the SetLocale() above
}
int main() // Thread One
{
// Create the mutexes and reset thread count.
hScreenMutex = CreateMutex(NULL, FALSE, NULL); // Cleared
ThreadNr = 0;
StartThreads();
// All threads done. Clean up handles.
CloseHandle(hScreenMutex);
getchar();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment