我一直在尝试在C上实现线程同步。但是,当我调用希望线程执行的函数时,我总是遇到分段错误。因此,任何人都可以提出针对该问题的解决方案?
这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define N 5
#define M 3
#define LEFT (robot_id - 1) % N
#define RIGHT (robot_id + 1) % N
pthread_t robots_id[N];
sem_t simulations[M];
pthread_mutex_t sever_mutex;
void Learning(int robot_id)
{
printf("learning robot = %d\n", robot_id);
}
void *robotAct(void *id)
{
int *robot_id = id;
printf("robot id = %d\n", robot_id);
Learning(*robot_id);
}
int main(int argc, char *argv[])
{
int E, T;
E = atoi(argv[1]);
T = atoi(argv[2]);
printf("Initializing Robot!\n");
//Initializes the simulations
for (int i = 0; i < M; i++)
{
sem_init(&simulations[i], 0, 0);
}
//Initializes the robots
for (int i = 0; i < N; i++)
{
printf("Robot %d is created\n", i + 1);
pthread_create(&robots_id[i], NULL, robotAct, (void *)i + 1);
}
sleep(T);
printf("Terminating Robots\n");
for (int i = 0; i < N; i++)
{
pthread_cancel(robots_id[i]);
}
printf("Termination is completed!\n");
printf("-------Report-------------\n");
//getReport();
return 0;
}
这是我不断得到的结果
Initializing Robot!
Robot 1 is created
Robot 2 is created
Robot 3 is created
robot id = 1
robot id = 2
Robot 4 is created
robot id = 3
[1] 54477 segmentation fault ./project 5 10
答案 0 :(得分:1)
主要问题在我的评论中进行了解释:
您没有将有效的指针传递给线程函数。在
printf()
的{{1}}调用中,您几乎可以避免滥用它;您着重在取消引用无效非指针的robotAct()
的调用中无法摆脱它。
一种解决方案是在主程序中创建一个包含机器人ID号(Learning()
)的整数数组。然后,初始化每个元素并将int id[N];
传递给&id[i]
。
您不应打印pthread_create()
格式的地址(即使它在32位系统上运行;在64位系统上也不运行)。正确的技术是使用%d
格式化地址。或者,在这种情况下,请使用%p
打印整数而不是地址。
以下代码对原始代码的适应性很小,并且尚未进行编译或测试(更改后的行可能有问题):
*robot_id
避免使用#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define N 5
#define M 3
#define LEFT (robot_id - 1) % N
#define RIGHT (robot_id + 1) % N
pthread_t robots_id[N];
sem_t simulations[M];
pthread_mutex_t sever_mutex;
void Learning(int robot_id)
{
printf("learning robot = %d\n", robot_id);
}
void *robotAct(void *id)
{
int *robot_id = id;
printf("robot id = %d\n", *robot_id); // Changed
Learning(*robot_id);
return 0; // Added
}
int main(int argc, char *argv[])
{
int E, T;
int id[N]; // Added
E = atoi(argv[1]);
T = atoi(argv[2]);
printf("Initializing Robot!\n");
//Initializes the simulations
for (int i = 0; i < M; i++)
{
sem_init(&simulations[i], 0, 0);
}
//Initializes the robots
for (int i = 0; i < N; i++)
{
printf("Robot %d is created\n", i + 1);
id[i] = i + 1; // Added
pthread_create(&robots_id[i], NULL, robotAct, &id[i]); // Changed
}
sleep(T);
printf("Terminating Robots\n");
for (int i = 0; i < N; i++)
{
pthread_cancel(robots_id[i]);
}
printf("Termination is completed!\n");
printf("-------Report-------------\n");
//getReport();
return 0;
}
结束线程;线程应在控制下终止。例如,您可能在主线程中设置了一个标志,以指示线程应该停止,并且它们会定期检查。通常,pthread_cancel()
用于清理完成的线程。
有关将来的帖子,请阅读有关如何创建MCVE(Minimal, Complete, Verifiable Example)的信息。显示的代码中有部分与问题无关—例如,互斥量和信号量并未真正使用。