首先说说DIR这一结构体,以下为DIR结构体的定义:
struct __dirstream
{
void __fd;
char __data;
int __entry_data;
char __ptr;
int __entry_ptr;
size_t __allocation;
size_t __size;
__libc_lock_define (, __lock)
};
typedef struct __dirstream DIR;
DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息(摘自《UNIX环境高级编程(第二版)》)。函数 DIR opendir(const char pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:
struct dirent readdir(DIR dp);
void rewinddir(DIR dp);
int closedir(DIR dp);
long telldir(DIR dp);
void seekdir(DIR dp,long loc);
关于DIR结构,我们知道这么多就可以了,没必要去再去研究他的结构成员。
接着是dirent结构体,首先我们要弄清楚目录文件(directory file)的概念:这种文件包含了其他文件的名字以及指向与这些文件有关的信息的指针(摘自《UNIX环境高级编程(第二版)》)。从定义能够看出,dirent不仅仅指向目录,还指向目录中的具体文件,readdir函数同样也读取目录下的文件,这就是证据。以下为dirent结构体的定义:
struct dirent
{
long d_ino; / inode number 索引节点号 /
off_t d_off; / offset to this dirent 在目录文件中的偏移 /
unsigned short d_reclen; / length of this d_name 文件名长 /
unsigned char d_type; / the type of d_name 文件类型 /
char d_name [NAME_MAX+1]; / file name (null-terminated) 文件名,最长255字符 /
}
然后是怎么使用它读取进程信息。可以用这些函数来读取/proc下的文件夹,然后做一个判断,只要文件夹的名字开头是1-9的,就进入目录读取其中的status文件,然后输出信息。
代码
#include <stdioh>
#include <direnth>
#include <unistdh>
#include <stdlibh>
typedef struct{
pid_t pid;
char name[256];//进程名称
int vmsize;//虚拟内存信息
}proc_info_st;//保存读取的进程信息
#define PROC_NAME_LINE 1//名称所在行
#define PROC_PID_LINE 4//pid所在行
#define PROC_VMSIZE_LINE 12//虚拟内存所在行
#define BUFF_LEN 1024 //行缓冲区的长度
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
void read_proc(proc_info_st info,const char c_pid);//读取进程信息
int read_line(FILE fp,char buff,int b_l,int l);//读取一行
int main()
{
//打开目录
DIR dir;
struct dirent ptr;
if (!(dir = opendir("/proc")))
return 0;
//读取目录
while (ptr = readdir(dir))
{//循环读取出所有的进程文件
if (ptr->d_name[0] > '0' && ptr->d_name[0] <= '9')
{
//获取进程信息
proc_info_st info;
read_proc(&info,ptr->d_name);//读取信息
printf("pid:%d\npname:%s\nvmsize:%d\n",infopid,infoname,infovmsize);
printf("\n\n");//再空两行
}
}
}
/
说明:根据进程pid获取进程信息,存放在proc_info_st结构体中
输入:
/proc_info_st info 返回进程信息
/char c_pid 进程pid的字符串形式
/
void read_proc(proc_info_st info,const char c_pid)
{
FILE fp = NULL;
char file[512] = {0};
char line_buff[BUFF_LEN] = {0};//读取行的缓冲区
sprintf(file,"/proc/%s/status",c_pid);//读取status文件
if (!(fp = fopen(file,"r")))
{
printf("read %s file fail!\n",file);
return;
}
char name[32];
//先读取进程名称
if (read_line(fp,line_buff,BUFF_LEN,PROC_NAME_LINE))
{
sscanf(line_buff,"%s %s",name,(info->name));
}
fseek(fp,0,SEEK_SET);//回到文件头部
//读取进程pid
if (read_line(fp,line_buff,BUFF_LEN,PROC_PID_LINE))
{
sscanf(line_buff,"%s %d",name,&(info->pid));
}
fseek(fp,0,SEEK_SET);//回到文件头部
//读取进程vmsize
if (read_line(fp,line_buff,BUFF_LEN,PROC_VMSIZE_LINE))
{
sscanf(line_buff,"%s %d",name,&(info->vmsize));
}
fclose(fp);
}
/
说明:读取文件的一行到buff
输入:
/FILE fp 文件指针
/char buff 缓冲区
/int b_l 缓冲区的长度
/l 指定行
输出:
/true 读取成功
/false 读取失败
/
int read_line(FILE fp,char buff,int b_l,int l)
{
if (!fp)
return FALSE;
char line_buff[b_l];
int i;
//读取指定行的前l-1行,转到指定行
for (i = 0; i < l-1; i++)
{
if (!fgets (line_buff, sizeof(line_buff), fp))
{
return FALSE;
}
}
//读取指定行
if (!fgets (line_buff, sizeof(line_buff), fp))
{
return FALSE;
}
memcpy(buff,line_buff,b_l);
return TRUE;
}
如果你想更深入的了解一些东西可以参考下>
这个问题需要的知识主要包括:
1 多进程间进行通信;
2 使用同步信号量(semaphore)和互斥信号量(mutex)进行数据保护。
参考代码如下,可以参照注释辅助理解:
#include <stdioh>#include <stdlibh>
#include <unistdh>
#include <pthreadh>
#include <semaphoreh>
#define N 2 // 消费者或者生产者的数目
#define M 10 // 缓冲数目
int in = 0; // 生产者放置产品的位置
int out = 0; // 消费者取产品的位置
int buff[M] = {0}; // 缓冲初始化为0, 开始时没有产品
sem_t empty_sem; // 同步信号量, 当满了时阻止生产者放产品
sem_t full_sem; // 同步信号量, 当没产品时阻止消费者消费
pthread_mutex_t mutex; // 互斥信号量, 一次只有一个线程访问缓冲
int product_id = 0; //生产者id
int prochase_id = 0; //消费者id
/ 打印缓冲情况 /
void print()
{
int i;
for(i = 0; i < M; i++)
printf("%d ", buff[i]);
printf("\n");
}
/ 生产者方法 /
void product()
{
int id = ++product_id;
while(1)
{
// 用sleep的数量可以调节生产和消费的速度,便于观察
sleep(1);
//sleep(1);
sem_wait(&empty_sem);
pthread_mutex_lock(&mutex);
in = in % M;
printf("product%d in %d like: \t", id, in);
buff[in] = 1;
print();
++in;
pthread_mutex_unlock(&mutex);
sem_post(&full_sem);
}
}
/ 消费者方法 /
void prochase()
{
int id = ++prochase_id;
while(1)
{
// 用sleep的数量可以调节生产和消费的速度,便于观察
sleep(1);
//sleep(1);
sem_wait(&full_sem);
pthread_mutex_lock(&mutex);
out = out % M;
printf("prochase%d in %d like: \t", id, out);
buff[out] = 0;
print();
++out;
pthread_mutex_unlock(&mutex);
sem_post(&empty_sem);
}
}
int main()
{
pthread_t id1[N];
pthread_t id2[N];
int i;
int ret[N];
// 初始化同步信号量
int ini1 = sem_init(&empty_sem, 0, M);
int ini2 = sem_init(&full_sem, 0, 0);
if(ini1 && ini2 != 0)
{
printf("sem init failed \n");
exit(1);
}
//初始化互斥信号量
int ini3 = pthread_mutex_init(&mutex, NULL);
if(ini3 != 0)
{
printf("mutex init failed \n");
exit(1);
}
// 创建N个生产者线程
for(i = 0; i < N; i++)
{
ret[i] = pthread_create(&id1[i], NULL, product, (void )(&i));
if(ret[i] != 0)
{
printf("product%d creation failed \n", i);
exit(1);
}
}
//创建N个消费者线程
for(i = 0; i < N; i++)
{
ret[i] = pthread_create(&id2[i], NULL, prochase, NULL);
if(ret[i] != 0)
{
printf("prochase%d creation failed \n", i);
exit(1);
}
}
//销毁线程
for(i = 0; i < N; i++)
{
pthread_join(id1[i],NULL);
pthread_join(id2[i],NULL);
}
exit(0);
}
在Linux下编译的时候,要在编译命令中加入选项-lpthread以包含多线程支持。比如存储的C文件为democ,要生成的可执行文件为demo。可以使用命令:
gcc democ -o demo -lpthread
程序中为便于观察,使用了sleep(1);来暂停运行,所以查看输出的时候可以看到,输出是每秒打印一次的。
以上就是关于Linux下怎么读取多个进程的信息全部的内容,包括:Linux下怎么读取多个进程的信息、C语言创建进程、在linux下用c语言实现用多进程同步方法演示“生产者-消费者”问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)