win+linux平台C语言获取进程的线程数量
进程内线程数量的浮动状态,是衡量软件是否稳定的一个指标。线程数量控制不好,将影响软件中其他功能的正常运行,可能会造成出现“Resource temporarily unavailable”的错误,乃至导致应用退出的可能。
1、linux平台,proc/pid/stat对应的内容结构
typedef struct
{
/** 01 */ pid_t pid; /** 进程号,其允许的最大值,请查看/proc/sys/kernel/pid_max */
/** 02 */ char comm[FILENAME_MAX]; /** 进程的名字,不包括路径 */
/** 03 */ char state; /** 进程的状态 */
/** 04 */ pid_t ppid; /** 父进程号 */
/** 05 */ pid_t pgrp; /** 进程组号 */
/** 06 */ pid_t session; /** 进程会话号 */
/** 07 */ int tty_nr; /** The tty the process uses */
/** 08 */ pid_t tpgid; /** The tty the process uses */
/** 09 */ unsigned int flags; /** The kernel flags word of the process (%lu before Linux 2.6.22) */
/** 10 */ unsigned long minflt; /** The number of minor faults the process has made which have not required loading a memory page from disk */
/** 11 */ unsigned long cminflt; /** The number of minor faults that the process's waited-for children have made */
/** 12 */ unsigned long majflt; /** The number of major faults the process has made which have required loading a memory page from disk */
/** 13 */ unsigned long cmajflt; /** The number of major faults that the process's waited-for children have made */
/** 14 */ unsigned long utime; /** The number of jiffies that this process has been scheduled in user mode */
/** 15 */ unsigned long stime; /** The number of jiffies that this process has been scheduled in kernel mode */
/** 16 */ long cutime; /** The number of jiffies that this process's waited-for children have been scheduled in user mode */
/** 17 */ long cstime; /** The number of jiffies that this process's waited-for children have been scheduled in kernel mode */
/** 18 */ long priority; /** The standard nice value, plus fifteen. The value is never negative in the kernel */
/** 19 */ long nice; /** The nice value ranges from 19 (nicest) to -19 (not nice to others) */
/** 20 */ long num_threads; /** Number of threads in this process (since Linux 2.6). Before kernel 2.6, this field was hard coded to 0 as a placeholder */
/** 21 */ long itrealvalue; /** The time in jiffies before the next SIGALRM is sent to the process due to an interval timer.2.6.17, this field is no longer maintained, and is hard coded as 0 */
/** 22 */ long long starttime; /** The time in jiffies the process started after system boot */
/** 23 */ unsigned long vsize; /** Virtual memory size in bytes */
/** 24 */ long rss; /** Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes */
/** 25 */ unsigned long rlim; /** Current limit in bytes on the rss of the process (usually 4294967295 on i386) */
/** 26 */ unsigned long startcode; /** The address above which program text can run */
/** 27 */ unsigned long endcode; /** The address below which program text can run */
/** 28 */ unsigned long startstack; /** The address of the start of the stack */
/** 29 */ unsigned long kstkesp; /** The current value of esp (stack pointer), as found in the kernel stack page for the process */
/** 30 */ unsigned long kstkeip; /** The current EIP (instruction pointer) */
/** 31 */ unsigned long signal; /** The bitmap of pending signals */
/** 32 */ unsigned long blocked; /** The bitmap of blocked signals */
/** 33 */ unsigned long sigignore; /** The bitmap of ignored signals */
/** 34 */ unsigned long sigcatch; /** The bitmap of caught signals */
/** 35 */ unsigned long nswap; /** Number of pages swapped (not maintained). */
/** 36 */ unsigned long cnswap; /** Cumulative nswap for child processes (not maintained) */
/** 37 */ int exit_signal; /** Signal to be sent to parent when we die (since Linux 2.1.22) */
/** 38 */ int processor; /** CPU number last executed on (since Linux 2.2.8) */
}process_info_t;
2、win+linux平台C语言获取进程内线程数量get_thread_count()
/*根据当前进程号,获取进程下线程数目*/
int get_thread_count()
{
int threads_in_process = 0;
#if defined (ACE_LINUX)
char filename[FILENAME_MAX];
ACE_OS::snprintf(filename, sizeof(filename)-1, "/proc/%u/stat", getpid());
FILE* fp = fopen(filename, "r");
if (NULL == fp) return -1;
char line[LINE_MAX];
int filed_number = 38;
process_info_t process_info;
char* linep = fgets(line, sizeof(line)-1, fp);
if (NULL == linep) return -1;
sscanf(line, "%d%s%s%d%d"
"%d%d%d%u%lu"
"%lu%lu%lu%lu%lu"
"%ld%ld%ld%ld%ld"
"%ld%lld%lu%ld%lu"
"%lu%lu%lu%lu%lu"
"%lu%lu%lu%lu%lu"
"%lu%d%d"
/** 01 */ ,&process_info.pid
/** 02 */ , process_info.comm
/** 03 */ ,&process_info.state
/** 04 */ ,&process_info.ppid
/** 05 */ ,&process_info.pgrp
/** 06 */ ,&process_info.session
/** 07 */ ,&process_info.tty_nr
/** 08 */ ,&process_info.tpgid
/** 09 */ ,&process_info.flags
/** 10 */ ,&process_info.minflt
/** 11 */ ,&process_info.cminflt
/** 12 */ ,&process_info.majflt
/** 13 */ ,&process_info.cmajflt
/** 14 */ ,&process_info.utime
/** 15 */ ,&process_info.stime
/** 16 */ ,&process_info.cutime
/** 17 */ ,&process_info.cstime
/** 18 */ ,&process_info.priority
/** 19 */ ,&process_info.nice
/** 20 */ ,&process_info.num_threads
/** 21 */ ,&process_info.itrealvalue
/** 22 */ ,&process_info.starttime
/** 23 */ ,&process_info.vsize
/** 24 */ ,&process_info.rss
/** 25 */ ,&process_info.rlim
/** 26 */ ,&process_info.startcode
/** 27 */ ,&process_info.endcode
/** 28 */ ,&process_info.startstack
/** 29 */ ,&process_info.kstkesp
/** 30 */ ,&process_info.kstkeip
/** 31 */ ,&process_info.signal
/** 32 */ ,&process_info.blocked
/** 33 */ ,&process_info.sigignore
/** 34 */ ,&process_info.sigcatch
/** 35 */ ,&process_info.nswap
/** 36 */ ,&process_info.cnswap
/** 37 */ ,&process_info.exit_signal
/** 38 */ ,&process_info.processor);
fclose(fp);
threads_in_process = (int)process_info.num_threads;
#else
int i = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
int processid = GetCurrentProcessId();
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "SkyDDS Warning, CreateToolhelp32Snapshot() failed. error code:%d.\n", GetLastError());
return 0;
}
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
while (bMore)
{
if (pe32.th32ProcessID == processid)
{
return pe32.cntThreads;
}
bMore = Process32Next(hProcessSnap, &pe32);
i++;
}
#endif
return threads_in_process;
}