A bit of an alternative way that hasn't been mentioned, but is definitely the most hassle-free:
int ret = unshare(CLONE_THREAD); // CLONE_SIGHAND and/or CLONE_VM also works
if (ret && errno == EINVAL) {
// we are multi-threaded
}
For single-threaded programs, this is a no-op. This won't allow you to see the amount of created threads, but that wasn't asked.
Source: unshare
man page:
In addition, CLONE_THREAD, CLONE_SIGHAND, and CLONE_VM can be specified in flags if the caller is single threaded (i.e., it is not sharing its address space with another process or thread). In this case, these flags have no effect. [...] If the process is multithreaded, then the use of these flags results in an error.
Edit: from your comments, it seems like this might be what you are looking for. It's a single system call and doesn't start any other processes.