现在有一个需求是,将正在运行的java程序的子线程分别绑定到不同的核心上
第一次尝试了taskset的方式,发现线程绑核不一定生效
ps -ef | grep java
这边得到了java运行的进程号pid,再通过pid去找它的线程
top -H -p 31178
输入'f'键,找到p = Last Used Cpu(SMP),按空格键选中,再按Esc退出,最后一列显示的则为绑定核心
通过taskset将线程绑定核心后,再通过top查看的时候,核心依旧没有改变
taskset -pc 2 31260
第二次尝试使用pthread_setaffinity_np函数去绑定核心,但是这边提供的方法都是将自己写的线程进行绑核,并没有办法去处理java线程的绑核操作
参考链接:https://www.jianshu.com/p/4522b8bf0e98
以下是我写的demo,其中没办法将获取到的线程tid转换成pthread_t的类型,pthread.h头文件中没有相应的转换函数
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
#include <string.h>
#include <sched.h>
#include <errno.h>
#define handle_error_en(en, msg) \
do {errno = en; perror(msg); exit(EXIT_FAILURE);} while (0)
int getProcessIdByExeName(const char* pName)
{
char buf[256]={0};
snprintf(buf, sizeof(buf), "ps -ef | grep \"%s\" | grep -v grep | awk '{print $2}'", pName);
FILE* fp = popen(buf, "r");
if (fp == NULL)
{
printf("popen failed, buf = %s", buf);
return -1;
}
char oBuf[256] = {0};
fgets(oBuf, 256, fp);
if (strlen(oBuf) == 0)
{
pclose(fp);
return -1;
}
oBuf[strlen(oBuf)-1] = '\0';
pclose(fp);
return atoi(oBuf);
}
// 将线程绑定到特定CPU核心的函数
int bind_thread_to_core(pthread_t thread, int core_id)
{
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
return pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
}
// 指定程序的所有子线程绑核
void set_threads_core_of_process(pid_t pid)
{
char cmd[256];
sprintf(cmd, "ps -T -p %d -o tid=", pid);
FILE* fp = popen(cmd, "r");
if (fp == NULL) {
perror("popen 失败");
return;
}
char tid_str[512];
fgets(tid_str, sizeof(tid_str), fp);
pclose(fp);
char* tid_token;
tid_token = strtok(tid_str, " ");
while (tid_token != NULL)
{
int tid = atoi(tid_token);
// 获取线程的详细信息并打印
sprintf(cmd, "ps -o pid,tid,psr,comm -p %d", tid);
fp = popen(cmd, "r");
if (fp == NULL) {
perror("popen 失败");
return;
}
char buffer[256];
fgets(buffer, sizeof(buffer), fp);
printf("%s", buffer);
pclose(fp);
// 将线程绑定到不同的CPU核心
int core_id = tid % sysconf(_SC_NPROCESSORS_ONLN); // 根据线程ID选择CPU核心
// 获取pthread_t对象,这边没办法将tid转换成pthread_t的类型
//pthread_t thread;
//bind_thread_to_core(thread, core_id);
tid_token = strtok(NULL, " ");
}
}
int main()
{
int ret = getProcessIdByExeName("java");
printf("java's pid = %d\n", ret);
set_threads_core_of_process(ret);
return 0;
}
所以有没有可以从线程tid可以得到pthread_t类型的方法,或者有没有其他什么方式可以实现,将正在运行的java进程的子线程分别绑定不同的cpu核心?
github上有个java的项目不知道是否能用
https://github.com/OpenHFT/Java-Thread-Affinity