advanced-ish C programming in Windows (pthreads, signals and semaphores, oh my!) - c

I'm in my third year studying computer science, so I should probably actually know the answer to this question already, but nonetheless, I don't. Anyway, I'm taking the OS course for my degree currently and we've been been covering a lot of new programming concepts like signals, semaphores, and threads in C. Unfortunately, my prof is covering all of these in a Linux/OS X perspective. What this means for me, being on a 64-bit windows machine, is that things like installing an alarm signal, or using semaphores and pthreads won't compile or run on my machine (as far as I can tell).
Anyway, currently I have just been doing my assignments in a VM running Linux, which has worked well so far, but I much prefer the Windows environment for coding.
So, after that heavy winded introduction, my question is, as you might have already guessed, is there a way to code with all these features (alarm signals, semaphores, pthreads, etc.) and be able to compile and test them in Windows? I'm fully aware that the Windows OS does not support the alarm signal and has limited POSIX capability, but I've heard rumors tossed around about cygwin (which I did try to get to work, but not very hard :P) and micro Linux kernels that you can run in the background to use these features.
Anyway, if anyone can give me maybe a list of options they would recommend (preferably not stick with your VM, even though I'm thinking that might be my best option) and maybe some tips, pros, cons, maybe a setup guide, or really any non-empty subset of these options I would really appreciate it. Also, before you ask, we have to use C and the above mentioned programming features in our assignments, so there's no switch to Java or code in win32 option unfortunately :(
Thanks in advance to anyone who can lend some words of wisdom :)

The basic principles are all there in Windows but done differently. And I recommend that, if you're going to program for Windows, you do this in the Windows API rather than through an emulation layer like Cygwin. If anything at all you'll quickly learn that different operating systems take a different approach to signalling and process handling.
First thing to be aware of is that threads are much more lightweight in Windows while processes are significantly more heavyweight. With that in mind Windows programs operate most efficiently when using threads. There is the concept of the CriticalSection that you should become very familiar with. And the Semaphore Object. Keep reading the API and you'll find a wealth of information about these topics - the Microsoft documentation is actually rather good. A key thing to understand about the Windows API is that you almost always have to "create/get" a new object (and obtain a handle) before you can use it. And Windows doesn't like programs having too many handles.
Personally I like the POSIX API and have a love for Linux. But I do appreciate that if you want to do things properly in Windows you should be using the Windows OS API - they have thought about this carefully even though the results and methods may be somewhat different.
PS Windows doesn't have the "alarm". It is perhaps the single most prohibitive barrier to simply porting Unix/Linux utilities to Windows. (That and the fact that Windows processes have to "bootstrap" Internet/socket support before using it whereas Linux processes are good to go).

There's MinGW-w64 - a Windows port of the GNU toolchain - and Pthreads-win32, a POSIX wrapper of the Windows threading API.
I'm using these via the mingw64-x86_64 Cygwin cross-compiler packages (which currently provide the somewhat dated gcc 4.5.3) instead of directly for two reasons: First, I need other stuff from the GNU toolbox, and second because of the package manager.
I'm not sure to what degree Pthreads-win32 complies to POSIX, but I can confirm that LLVM and Clang both compile with this setup.

Related

Is it fine to use linux code compiled on cygwin for production in windows?

I have a working module on linux and one of the client wants it on windows.
There is very good discussion on similar topic here(https://ask.slashdot.org/story/04/08/12/1932246/cygwin-in-a-production-environment), I guess it leaning towards avoiding cygwin for productions but its about 13 years older discussion,there might have been issues but in about 13 years I hope cygwin might have been improved,matured and good for production use.
The code compiled just fine and seems to work ok under cygwin so its very tempting to take it forward rather than redoing it in windows native code.
But if there are really any unsolvable known issues and people are avoiding it for productions I would like to know.
The code heavily uses pthreads,sockets in no-wait
I've used Cygwin a fair bit, and have found it mostly unproblematic. I am aware of some of the reported problems, but haven't experienced them myself. Some things on Cygwin are much slower than the same code on Linux -- I notice this most with directory scans, but that probably isn't the only thing. People complain about fork() being slow, but that isn't really a surprise, as 'forking' isn't a native concept in Windows. If you're just using fork() to launch subprocesses, then conceivably the whole fork/exec thing could selectively be replaced with calls to native Windows APIs.
A potential limitation of Cygwin is that it requires Cygwin at run-time or, at least, a chunk of Cygwin infrastructure. MinGW might remove this restriction, but at the cost of leaving you to make a larger number of compatibility-related changes in your code (file locations, for example). The last time I looked, MinGW didn't have tooling as extensive as Cygwin, either, but it's probably good enough for many purposes.
I guess another possibility to consider these days is the Windows Subsystem for Linux (WSL) on Windows 10. I've found that code that builds for Cygwin usually builds and runs without changes on WSL, but I haven't really figured out what the relative advantages and disadvantages of Cygwin and WSL are.
I've not noticed problems with pthreads in Cygwin, MinGW, or WSL; although I guess any problems are likely to depend on the exact way you use threads. I can't comment on the no-wait socket issue, because that isn't something I've tried.
Incidentally, both Cygwin and MinGW will allow you to call native Windows API, and other functions in DLLs, if you need to. So the possibility exists to create a sort of "hybrid" application that uses POSIX-type functions and also Win32 APIs. This might be useful if it turns out that some things are much faster with Win32 functionality. I'm not sure this is possible with WSL.
I should say that my comment about time consuming updates refers as much to the need to perform a full Windows update as well as apt-get updates prior to running a wsl
script which will go past midnight. Running a separate memory recovery script every 4 hours or so is a partial solution. I have "only " 6GB RAM.

Coding in C in Linux vs Windows. Any adequate debugging oriented C-centric IDE?

I've run into an issue with writing some code in c. My basic problem is that I am pressed for time and the code I am dealing with has lots of bugs which I have to "erradicate" before tomorrow evening.
The bigger part of the problem is that there is no adequate IDE that can do real time debugging, especially when using threads or spawning processes with fork(). I tried Mono, Eclipse, and finally NetBeans, and have concluded that those are very good but not for coding in C. More over the learning curve to utilize the command line debugger properly is quite steep. (Like I mentioned earlier... I am pressed on time.)
So, since I am a C# developer by profession I was wondering whether I can pull this off in VS2003/VS2005/VS2008/VS2010. If I abstain from using system calls, can I do this?
Of particular interest are FILE* descriptor and fread(), fclose(), fseek() methods. I know they are part of the standard C library, however are they tied to the platform itself? Are the headers the same in Linux vs Windows? What about fork() or shared memory?
Maybe if I use VS2010 to build parts of the component at a time (by mocking inputs and stuff), debug those, and then migrate the working code in the overall Linux project would prove most useful?
Any input would be greatly appreciated.
The bigger part of the problem is that there is no adequate IDE that can do real time debugging, especially when using threads or spawning processes with fork().
The Eclipse CDT would probably have the best overall support for C/C++ development and integrated debugging.
Note that multithreaded and multiprocess debugging can be difficult at the best of times. Investing in a good logging framework would be advisable at this point, and probably more useful than relying on a debugger. There are many to choose from - have a look at Log4C++ and so on. Even printf in a pinch can be invaluable.
So, since I am a C# developer by profession I was wondering whether I can pull this off in VS2003/VS2005/VS2008/VS2010. If I abstain from using system calls, can I do this?
If you take care to only use portable calls and not Win32-specific APIs, you should be ok. Also, there are many libraries (for C++ libraries such as Boost++ that provide a rich set of functionality which work the same on Windows, Linux and others.
Of particular interest are FILE* descriptor and fread(), fclose(), fseek() methods. I know they are part of the standard C library, however are they tied to the platform itself? Are the headers the same in Linux vs Windows? What about fork() or shared memory?
Yes, the file I/O functions you mention are in <stdio.h> and part of the portable standard C library. They work essentially the same on both Windows and Linux, and are not tied to a particular platform.
However, fork() and the shared memory functions shmget() are POSIX functions, available on *nix platforms but not natively on Windows. The Cygwin project provides implementations of these functions in a library for ease of porting.
If you are using C++, Boost++ will give you portable versions of all these system-level calls.
Maybe if I use VS2010 to build parts of the component at a time (by mocking inputs and stuff), debug those, and then migrate the working code in the overall Linux project would prove most useful?
You could certainly do that. Just be mindful that Visual Studio has a tendency to lead you down the Win32 path, and you must be vigilant to not start using non-portable functions. Fortunately the library reference on MSDN gives you the compatibility information. In general, using standard C or POSIX calls will be portable. In my experience, it is actually easier to write on *nix and port to Windows, but YMMV.
Looks like I am the first to recommend Emacs here. Here is how Emacs works. When you install it, it is simply a text editor with a lot of extensions(debugger and C font-locking are included by default). As you start using it and install the extensions you miss, it becomes more than just an editor. It grows to become an IDE very soon and easily, then on to something that can eschew the OS under one frame.
Emacs might take long to learn, in the mean time, you could use Visual Slick Edit if you are not pressed on the cost part. I have used it on both platforms and seen it work good with version control, tags, etc.
Perhaps Code::Blocks? I love it and while it says it's for C++ it is, of course, very good for plain C as well.

Porting a large C project from Unix to Windows

So, I have a large C project that was built entirely on Unix (SPARC Solaris). me and several others have begun to revisit it because their was some interest in a windows build.
none of us have done this with a project of such size, so for starters, has anyone ported something from unix to windows and could maybe give me some pointers or how they did it.
our first step on our plan was to decide on a compiler/dev environment.
it seems that our options are MS Visual Studio, Cygwin, mingw/gcc, and Windows Services for UNIX (SFU).
we are on a fairly short timetable so we want to rewrite as little code as possible.
so, Deciding on a compiler.
Another issue is that the code does use POSIX thread commands (pthread, etc)
we would prefer to compile natively, not using some sort of layer between the executable and the OS. unfortunatly with the pthread calls in our code, this may not be possible.
I believe both Cygwin and SFU do just that. Cygwin has a .dll that must be included in compiled code to work. I am not sure about SFU, any information about that would be greatly appreciated. It seems like it would be a good option but was developed to allow for UNIX compiled software to run on a windows machine with SFU, not any old windows box.
mingw does have the ability to create native exes, but lacks the POSIX support.
So, can anyone give me any more information, suggestions, knowledge on any of these compilers in this context. or any experience they have with this sort of thing, it is greatly appreciated.
Short timetable? CygWin, plain and simple.
Despite your preference to not use a layer, that's going to provide the fastest path and you don't seem to indicate that the timeframe requirement is flexible.
We've ported both command-line and X-based UNIX programs to Windows using CygWin with minimal hassle.
Cygwin is likely the fastest path to a working executable. However it will leave you with some interesting distribution choices. Most obviously, cygwin.dll becomes a dependency. Its licensed GPL, unless you pay money to buy commercial use rights.
Cygwin is not particularly friendly to an ordinary Windows user. Its goal is to provide a full POSIX experience on Windows, supplying a shell, all the familiar *nix utilities, and even a port of X. However, it also remaps the Windows disk drive naming into a POSIX-like file system. I've never attempted to distribute an application built for Cygwin to machines that don't already have a full Cygwin installation. I will note that to my knowledge none of the big well-known open-source applications with Windows ports are based on Cygwin.
If the only hard POSIX dependency you have is pthreads, then that is solvable. There is a pthreads port built on native Windows threads that works well with MinGW. IIRC, it is even distributed along with MinGW, or at least is one of their core supported packages.
If the rest of your handling of file names is largely as opaque strings, you may not even need to care about changing / to \. The Windows API is generally happy to treat either character as a path separator, even mixed in the same name. It is the CMD.EXE and early DOS convention of using / for command line options that prevents the use of / for pathnames at the command prompt, not the underlying Windows API.
For tools that might make porting your build process easier, check out the MSYS component of MinGW. It provides a lightweigh fork from the Cygwin environment in which enough *nix utilities are available to generally run ./configure and similar processes.
In addition, the GnuWin32 project has ports of a large number of utilities and libraries that are all built to run as native Windows applications without unusual dependencies.
If the code is (at least mostly) portable and the only major issue is the use of pthreads, you might want to use the Pthreads Win32 library. While incomplete, it's sufficiently complete and accurate to deal with most pthreads code I've tried it with. While normally built as a DLL, this can also be built as a static library to avoid creating an extra dependencies in your executable.
That, of course, leaves everything else to port -- but you haven't said enough to even guess whether porting the rest within your timeframe is at all reasonable.

Which is better for windows? pthreads or CreateMutex?

I am porting my application to windows from Linux. I am fairly new to the fine-art of porting application across platforms. As far as I know, Windows does not natively support POSIX threads implementation. Is this true? I have heard about some implementation of pthreads for windows (a wrapper or something), would it be better to use them or use CreateMutex and other APIs provided by windows???? Someone pls. enlighten me with the PROs and CONs of both worlds. Some miscellaneous tips for porting would go nicely along with the answer.
Thanks in advance.
It's all going to be the same stuff (pthreads is just going to call EnterCriticalSection etc), so if you've got a pthreads wrapper, you should probably use it so that you don't have to change as much code
this works well: http://sourceware.org/pthreads-win32/
It is a port of the pthreads library for Windows.
One thing you need to keep in mind is what is the future of this code. Do you plan on developing (and releasing) on both platforms in the future? Or is this a one way port?
The best thing to do when porting a project is to keep the actual changes to the code as minimal as possible. In your case, this would mean going with a pthread solution. That being said, if you are planning this to be a one way port, going native never hurts. :)
I would take some time to fully examine both stratigies and then implement the one you feel most comfortable with.
The first thing I'd do is to port to Boost Thread under Linux than to Windows.
Why not have the best of both worlds and use a library that wraps both pthreads and Window's API and uses the appropriate one under the covers? Your code stays the same on both platforms.
There are no shortage of such libs in C++ so I can't imagine there aren't C versions about.
On Windows C/C++ applications that use the CRT need to call beginthread/beginthreadex to properly initialize the CRT in the new thread.

Writing cross-platform apps in C

What things should be kept most in mind when writing cross-platform applications in C? Targeted platforms: 32-bit Intel based PC, Mac, and Linux. I'm especially looking for the type of versatility that Jungle Disk has in their USB desktop edition ( http://www.jungledisk.com/desktop/download.aspx )
What are tips and "gotchas" for this type of development?
I maintained for a number of years an ANSI C networking library that was ported to close to 30 different OS's and compilers. The library didn't have any GUI components, which made it easier. We ended up abstracting out into dedicated source files any routine that was not consistent across platforms, and used #defines where appropriate in those source files. This kept the code that was adjusted per platform isolated away from the main business logic of the library. We also made extensive use of typedefs and our own dedicated types so that we could easily change them per platform if needed. This made the port to 64-bit platforms fairly easy.
If you are looking to have GUI components, I would suggest looking at GUI toolkits such as WxWindows or Qt (which are both C++ libraries).
Try to avoid platform-dependent #ifdefs, as they tend to grow exponentially when you add new platforms. Instead, try to organize your source files as a tree with platform-independent code at the root, and platform-dependent code on the "leaves". There is a nice book on the subject, Multi-Platform Code Management. Sample code in it may look obsolete, but ideas described in the book are still brilliantly vital.
Further to Kyle's answer, I would strongly recommend against trying to use the Posix subsystem in Windows. It's implemented to an absolute bare minimum level such that Microsoft can claim "Posix support" on a feature sheet tick box. Perhaps somebody out there actually uses it, but I've never encountered it in real life.
One can certainly write cross-platform C code, you just have to be aware of the differences between platforms, and test, test, test. Unit tests and a CI (continuous integration) solution will go a long way toward making sure your program works across all your target platforms.
A good approach is to isolate the system-dependent stuff in one or a few modules at most. Provide a system-independent interface from that module. Then build everything else on top of that module, so it doesn't depend on the system you're compiling for.
XVT have a cross platform GUI C API which is mature 15+ years and sits on top of the native windowing toollkits. See WWW.XVT.COM.
They support at least LINUX, Windows, and MAC.
Try to write as much as you can with POSIX. Mac and Linux support POSIX natively and Windows has a system that can run it (as far as I know - I've never actually used it). If your app is graphical, both Mac and Linux support X11 libraries (Linux natively, Mac through X11.app) and there are numerous ways of getting X11 apps to run on Windows.
However, if you're looking for true multi-platform deployment, you should probably switch to a language like Java or Python that's capable of running the same program on multiple systems with little or no change.
Edit: I just downloaded the application and looked at the files. It does appear to have binaries for all 3 platforms in one directory. If your concern is in how to write apps that can be moved from machine to machine without losing settings, you should probably write all your configuration to a file in the same directory as the executable and not touch the Windows registry or create any dot directories in the home folder of the user that's running the program on Linux or Mac. And as far as creating a cross-distribution Linux binary, 32-bit POSIX/X11 would probably be the safest bet. I'm not sure what JungleDisk uses as I'm currently on a Mac.
There do exist quite few portable libraries just examples I've worked within the past
1) glib and gtk+
2) libcurl
3) libapr
Those cover nearly every platform and so they are extremly useful tool.
Posix is fine on Unices but well I doubt it's that great on windows, besides we do not have any stuff for portable GUIs there.
I also second the recommendation to separate code for different platforms into different modules/trees instead of ifdefs.
Also I recommend to check beforehand what are the differences in you platforms and how you could abstract them. E.g. this is some OS related stuff (e.g. the annoying CR,CRLF,LF in text files), or hardware stuff. E.g. the previous mentioned posix compability doesnt stop you from
int c;
fread(&c, sizeof(int), 1, file);
But on different hardware platforms the internal memory layout can be complete different (endianess), forcing you to use conversion functions on some of the target platforms.
You can use NAppGUI for both console and desktop apps. The SDK uses ANSI-C and your code will work on Windows/macOS/Linux.
https://www.nappgui.com
It's free and OpenSource.

Resources