使用 pthread_create 时出现段错误
Seg Fault when using pthread_create
我在使用 pthread_create 时难以创建线程,我尝试将函数更改为 void* 等,但它一直抛出分段错误。
任何解决此问题的帮助将不胜感激,我已尝试研究此问题但无济于事我还没有找到解决方案
下面是我的代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <ctype.h>
#include <getopt.h>
#include <stdbool.h>
void readSudoku(int x[][9], FILE *in);
void printSudoku(int x[][9]);
int validateRows(int x[9][9]);
int validateCols(int x[9][9]);
int validateSubGrids(int x[9][9]);
void *vr(int x[9][9]);
void *vc(int x[9][9]);
void *vs(int x[9][9]);
bool validSudokuGrid(int x[][9]);
/* These are the only two global variables allowed in your program */
static int verbose = 0;
static int use_fork = 0;
// This is a simple function to parse the --fork argument.
// It also supports --verbose, -v
void parse_args(int argc, char *argv[])
{
int c;
while (1)
{
static struct option long_options[] =
{
{"verbose", no_argument, 0, 'v'},
{"fork", no_argument, 0, 'f'},
{0, 0, 0, 0}};
int option_index = 0;
c = getopt_long(argc, argv, "vf", long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 'f':
use_fork = 1;
break;
case 'v':
verbose = 1;
break;
default:
exit(1);
}
}
}
int main(int argc, char *argv[])
{
// Commented this out because this will be used later
// parse_args(argc, argv);
// if (verbose && use_fork) {
// printf("We are forking child processes as workers.\n");
// } else if (verbose) {
// printf("We are using worker threads.\n");
// }
// printf("Test");
// Initializing sudoku grid to parse file grid
int sudoku_grid[9][9];
if (argc == 1)
{
printf("File successfully opened!\n");
}
readSudoku(sudoku_grid, stdin);
printSudoku(sudoku_grid);
// validateRows(sudoku_grid);
// validateCols(sudoku_grid);
if (validSudokuGrid(sudoku_grid))
{
printf("The input is a valid Sudoku. \n");
}
else
{
printf("The input is not a valid Sudoku. \n");
}
return 0;
}
void readSudoku(int x[][9], FILE *in)
{
fseek(in, -1, SEEK_CUR); // Seek to start off the current position of the file ptr
char entry;
int i, j, totalVals = 0;
while ((fread(&entry, 1, 1, in)) > 0 && totalVals < 81)
{ // Read 81 digits from stdin file
if (entry != '\n')
{ // Ignore newline
if (isdigit(entry))
{
++totalVals;
x[i][j] = entry - '0'; // Store integer representation
++j;
if (j == 9)
{
j = 0;
++i;
}
}
}
}
}
void printSudoku(int x[][9])
{
int i = 0, j = 0; // i = rows, j = cols
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
// if we are on the third or fifth number of sub-grid
// we make a space between nums
if (2 == j || 5 == j)
{
printf("%d ", x[i][j]);
}
// if we are on the last num of row we make a space
else if (8 == j)
{
printf("%d\n", x[i][j]);
}
// anything else we make a space
else
{
printf("%d ", x[i][j]);
}
}
// if we are on row 3 or row 5 we make a space
if (2 == i || 5 == i)
{
printf("\n");
}
}
}
// Used to validate rows per 3x3 grid
int validateRows(int x[9][9])
{
for (int i = 0; i < 9; i += 3)
{
for (int j = 0; j < 9; j += 3)
{
int subgridValidate[9] = {0};
for (int k = i; k < i + 3; k++)
{
for (int m = j; m < j + 3; m++)
{
int currVal = x[k][m];
if (subgridValidate[currVal - 1] == 0)
{
subgridValidate[currVal - 1] = 1;
}
// else
// {
// // printf("row: %d, col: %d", k+1, m+1);
// // printf("Row: %d does not have required values \n", k + 1);
// // printf("Column: %d does not have required values \n", m + 1);
// return 0;
// }
else if((subgridValidate[currVal - 1] == 1) && (k >= 0 && k <=2)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if ( m >= 3 && m <= 5 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if ( m >= 6 && m <= 8 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 3 && k <=5) ) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 6 && k <=8)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
}
else //all subgrid have correct values.
{
return 1; // true
}
}
}
}
}
}
// Validating columns in the 3x3 grid *BACK UP*
// Fixing column tracking
// int validateCols(int x[9][9]) {
// int col = 0;
// // Traversing Rows
// for(int i = 0; i < 9; i++) {
// // Initialzing array to detect for duplicate values
// int colValidate[9] = {0};
// // Traversing columns
// for(int j = 0; j < 9; j++) {
// // Holds current value depending on row / col
// int currVal = x[i][j];
// // If the index is filled with a zero
// // that means the index is not taken
// if(colValidate[currVal - 1] == 0) {
// colValidate[currVal - 1] = 1; // fill index with 1 (true)
// } else { // Checks if dupllicate or out of bounds
// printf("Column: %d does not have the required values\n", j + 1);
// return 0;
// }
// } col ++;
// }
// }
// Function to check 3x3 Sub-Grids
int validateCols(int x[9][9])
{
for (int i = 0; i < 9; i += 3)
{
for (int j = 0; j < 9; j += 3)
{
int subgridValidate[9] = {0};
for (int k = i; k < i + 3; k++)
{
for (int m = j; m < j + 3; m++)
{
int currVal = x[k][m];
if (subgridValidate[currVal - 1] == 0)
{
subgridValidate[currVal - 1] = 1;
}
// else
// {
// // printf("row: %d, col: %d", k+1, m+1);
// // printf("Row: %d does not have required values \n", k + 1);
// // printf("Column: %d does not have required values \n", m + 1);
// return 0;
// }
else if((subgridValidate[currVal - 1] == 1) && (k >= 0 && k <=2)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if ( m >= 3 && m <= 5 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if ( m >= 6 && m <= 8 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 3 && k <=5) ) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 6 && k <=8)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
}
else //all subgrid have correct values.
{
return 1; // true
}
}
}
}
}
}
// Needs intense fixing
int validateSubGrids(int x[9][9])
{
for (int i = 0; i < 9; i += 3)
{
for (int j = 0; j < 9; j += 3)
{
int subgridValidate[9] = {0};
for (int k = i; k < i + 3; k++)
{
for (int m = j; m < j + 3; m++)
{
int currVal = x[k][m];
if (subgridValidate[currVal - 1] == 0)
{
subgridValidate[currVal - 1] = 1;
}
// else
// {
// // printf("row: %d, col: %d", k+1, m+1);
// // printf("Row: %d does not have required values \n", k + 1);
// // printf("Column: %d does not have required values \n", m + 1);
// return 0;
// }
else if((subgridValidate[currVal - 1] == 1) && (k >= 0 && k <=2)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("The top left subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if ( m >= 3 && m <= 5 ){
printf("The top mid subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if ( m >= 6 && m <= 8 ){
printf("The top right subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 3 && k <=5) ) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("The left subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("The left mid subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("The left right subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 6 && k <=8)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("The bottom left subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("The bottom mid subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("The bottom right subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
}
else //all subgrid have correct values.
{
return 1; // true
}
}
}
}
}
}
void *vr(int x[9][9]) {
validateRows(x);
}
void *vc(int x[9][9]) {
validateCols(x);
}
void *vs(int x[9][9]) {
validateSubGrids(x);
}
bool validSudokuGrid(int x[][9])
{
int numThreads = 2;
pthread_t tid [2];
for(int i = 0; i < 1; i++) {
if(i == 0) {
pthread_create(&tid[i], NULL, vr(x), NULL);
} else if(i == 1) {
pthread_create(&tid[i], NULL, vc(x), NULL);
} else {
pthread_create(&tid[i], NULL, vc(x), NULL);
}
printf("OOOGA BOOGA");
}
printf("OOOGA BOOGA");
for (int i = 0; i < numThreads; i++) {
pthread_join(tid[i], NULL);
printf("Thread %10x joined\n", tid[i]);
fflush(stdout);
}
printf("All Four Threads have exited using join(), exiting program....\n");
fflush(stdout);
exit(EXIT_SUCCESS);
return validateRows(x) + validateCols(x) + validateSubGrids(x); // if all true = valid 9x9, else = not valid 9x9
// return validateSubGrids(x);
}
Pthreads 需要 void* func (void*)
形式的回调函数,句号。您不能发明自己的函数格式并期望它起作用。
此外 vr(x)
等参数是 函数调用 - 你调用函数一次然后使用它的结果告诉 pthread_create
它是一个指针到回调函数,它不是 - 这只是胡说八道。
此外,具有 return 类型的函数必须始终 return
某些内容。
所有这些问题都可以通过正确配置编译器在早期避免,因此它会在遇到明显的错误和无效的 C 时给出错误,请参阅 What compiler options are recommended for beginners learning C? 正确使用函数是非常基础的东西,你在进入更高级的主题之前需要掌握,例如 multi-threading.
正确使用,正如友情所说 man:
void* vr (void* x) {
validateRows(x);
return NULL;
}
...
pthread_create(&tid[i], NULL, vr, x);
我不确定你的代码是否编译,但如果编译成功,那么会发生什么:当程序 运行s,然后在 pthread_create() 函数中,它将调用你的函数vr() 并使用 vr() 的 return 值作为指向创建线程时应调用的函数的指针。
但是vr()没有return任何值,但在这里并不重要。
任何函数的return值根据系统存储在某处(寄存器等)。假设 return 值存储在名为 A 的寄存器中。因此,将调用 vr(x),然后读取寄存器 A 中的值,然后代码将假定该值是指向应该调用的函数。但是 A 可以有任何值(因为函数 vr(x) 没有 return 任何值,因此它没有更新 A)- 0x0、0x1、0x75745 等。而且大多数情况下这将是一个无效地址(可能会指向受限内存区域,或只读内存等)因此硬件会引发内存访问冲突 interrupt/signal,然后导致分段错误。
运行下面的代码你就明白我在说什么了
#include <stdio.h>
#include <pthread.h>
void *f(void *g)
{
printf("Called f().\n");
}
void *x(void *v)
{
printf("Called x().\n");
return (void *)(f);
}
int main(void)
{
pthread_t pt;
pthread_create(&pt, NULL, x((void *)5), NULL);
// join pthread.
pthread_join(pt, NULL);
return 0;
}
当您 运行 上面的代码时,函数 x() 和 f() 都会被调用。
输出将是:
调用了 x()。
调用了 f()。
我在使用 pthread_create 时难以创建线程,我尝试将函数更改为 void* 等,但它一直抛出分段错误。
任何解决此问题的帮助将不胜感激,我已尝试研究此问题但无济于事我还没有找到解决方案
下面是我的代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <ctype.h>
#include <getopt.h>
#include <stdbool.h>
void readSudoku(int x[][9], FILE *in);
void printSudoku(int x[][9]);
int validateRows(int x[9][9]);
int validateCols(int x[9][9]);
int validateSubGrids(int x[9][9]);
void *vr(int x[9][9]);
void *vc(int x[9][9]);
void *vs(int x[9][9]);
bool validSudokuGrid(int x[][9]);
/* These are the only two global variables allowed in your program */
static int verbose = 0;
static int use_fork = 0;
// This is a simple function to parse the --fork argument.
// It also supports --verbose, -v
void parse_args(int argc, char *argv[])
{
int c;
while (1)
{
static struct option long_options[] =
{
{"verbose", no_argument, 0, 'v'},
{"fork", no_argument, 0, 'f'},
{0, 0, 0, 0}};
int option_index = 0;
c = getopt_long(argc, argv, "vf", long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 'f':
use_fork = 1;
break;
case 'v':
verbose = 1;
break;
default:
exit(1);
}
}
}
int main(int argc, char *argv[])
{
// Commented this out because this will be used later
// parse_args(argc, argv);
// if (verbose && use_fork) {
// printf("We are forking child processes as workers.\n");
// } else if (verbose) {
// printf("We are using worker threads.\n");
// }
// printf("Test");
// Initializing sudoku grid to parse file grid
int sudoku_grid[9][9];
if (argc == 1)
{
printf("File successfully opened!\n");
}
readSudoku(sudoku_grid, stdin);
printSudoku(sudoku_grid);
// validateRows(sudoku_grid);
// validateCols(sudoku_grid);
if (validSudokuGrid(sudoku_grid))
{
printf("The input is a valid Sudoku. \n");
}
else
{
printf("The input is not a valid Sudoku. \n");
}
return 0;
}
void readSudoku(int x[][9], FILE *in)
{
fseek(in, -1, SEEK_CUR); // Seek to start off the current position of the file ptr
char entry;
int i, j, totalVals = 0;
while ((fread(&entry, 1, 1, in)) > 0 && totalVals < 81)
{ // Read 81 digits from stdin file
if (entry != '\n')
{ // Ignore newline
if (isdigit(entry))
{
++totalVals;
x[i][j] = entry - '0'; // Store integer representation
++j;
if (j == 9)
{
j = 0;
++i;
}
}
}
}
}
void printSudoku(int x[][9])
{
int i = 0, j = 0; // i = rows, j = cols
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
// if we are on the third or fifth number of sub-grid
// we make a space between nums
if (2 == j || 5 == j)
{
printf("%d ", x[i][j]);
}
// if we are on the last num of row we make a space
else if (8 == j)
{
printf("%d\n", x[i][j]);
}
// anything else we make a space
else
{
printf("%d ", x[i][j]);
}
}
// if we are on row 3 or row 5 we make a space
if (2 == i || 5 == i)
{
printf("\n");
}
}
}
// Used to validate rows per 3x3 grid
int validateRows(int x[9][9])
{
for (int i = 0; i < 9; i += 3)
{
for (int j = 0; j < 9; j += 3)
{
int subgridValidate[9] = {0};
for (int k = i; k < i + 3; k++)
{
for (int m = j; m < j + 3; m++)
{
int currVal = x[k][m];
if (subgridValidate[currVal - 1] == 0)
{
subgridValidate[currVal - 1] = 1;
}
// else
// {
// // printf("row: %d, col: %d", k+1, m+1);
// // printf("Row: %d does not have required values \n", k + 1);
// // printf("Column: %d does not have required values \n", m + 1);
// return 0;
// }
else if((subgridValidate[currVal - 1] == 1) && (k >= 0 && k <=2)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if ( m >= 3 && m <= 5 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if ( m >= 6 && m <= 8 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 3 && k <=5) ) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 6 && k <=8)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Row: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", k + 1);
return 0;
}
}
else //all subgrid have correct values.
{
return 1; // true
}
}
}
}
}
}
// Validating columns in the 3x3 grid *BACK UP*
// Fixing column tracking
// int validateCols(int x[9][9]) {
// int col = 0;
// // Traversing Rows
// for(int i = 0; i < 9; i++) {
// // Initialzing array to detect for duplicate values
// int colValidate[9] = {0};
// // Traversing columns
// for(int j = 0; j < 9; j++) {
// // Holds current value depending on row / col
// int currVal = x[i][j];
// // If the index is filled with a zero
// // that means the index is not taken
// if(colValidate[currVal - 1] == 0) {
// colValidate[currVal - 1] = 1; // fill index with 1 (true)
// } else { // Checks if dupllicate or out of bounds
// printf("Column: %d does not have the required values\n", j + 1);
// return 0;
// }
// } col ++;
// }
// }
// Function to check 3x3 Sub-Grids
int validateCols(int x[9][9])
{
for (int i = 0; i < 9; i += 3)
{
for (int j = 0; j < 9; j += 3)
{
int subgridValidate[9] = {0};
for (int k = i; k < i + 3; k++)
{
for (int m = j; m < j + 3; m++)
{
int currVal = x[k][m];
if (subgridValidate[currVal - 1] == 0)
{
subgridValidate[currVal - 1] = 1;
}
// else
// {
// // printf("row: %d, col: %d", k+1, m+1);
// // printf("Row: %d does not have required values \n", k + 1);
// // printf("Column: %d does not have required values \n", m + 1);
// return 0;
// }
else if((subgridValidate[currVal - 1] == 1) && (k >= 0 && k <=2)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if ( m >= 3 && m <= 5 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if ( m >= 6 && m <= 8 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 3 && k <=5) ) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 6 && k <=8)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("Column: %d does not have required values (either a duplicate or value not in range of 1 - 9) \n", m + 1);
return 0;
}
}
else //all subgrid have correct values.
{
return 1; // true
}
}
}
}
}
}
// Needs intense fixing
int validateSubGrids(int x[9][9])
{
for (int i = 0; i < 9; i += 3)
{
for (int j = 0; j < 9; j += 3)
{
int subgridValidate[9] = {0};
for (int k = i; k < i + 3; k++)
{
for (int m = j; m < j + 3; m++)
{
int currVal = x[k][m];
if (subgridValidate[currVal - 1] == 0)
{
subgridValidate[currVal - 1] = 1;
}
// else
// {
// // printf("row: %d, col: %d", k+1, m+1);
// // printf("Row: %d does not have required values \n", k + 1);
// // printf("Column: %d does not have required values \n", m + 1);
// return 0;
// }
else if((subgridValidate[currVal - 1] == 1) && (k >= 0 && k <=2)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("The top left subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if ( m >= 3 && m <= 5 ){
printf("The top mid subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if ( m >= 6 && m <= 8 ){
printf("The top right subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 3 && k <=5) ) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("The left subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("The left mid subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("The left right subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
}
else if((subgridValidate[currVal - 1] == 1) && (k >= 6 && k <=8)) { // checks for dupes, segfaults if num > 9
if( m >= 0 && m <= 2 ){
printf("The bottom left subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 3 && m <= 5 ){
printf("The bottom mid subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
else if( m >= 6 && m <= 8 ){
printf("The bottom right subgrid does not have the required values (either a duplicate or value not in range of 1 - 9)\n");
return 0;
}
}
else //all subgrid have correct values.
{
return 1; // true
}
}
}
}
}
}
void *vr(int x[9][9]) {
validateRows(x);
}
void *vc(int x[9][9]) {
validateCols(x);
}
void *vs(int x[9][9]) {
validateSubGrids(x);
}
bool validSudokuGrid(int x[][9])
{
int numThreads = 2;
pthread_t tid [2];
for(int i = 0; i < 1; i++) {
if(i == 0) {
pthread_create(&tid[i], NULL, vr(x), NULL);
} else if(i == 1) {
pthread_create(&tid[i], NULL, vc(x), NULL);
} else {
pthread_create(&tid[i], NULL, vc(x), NULL);
}
printf("OOOGA BOOGA");
}
printf("OOOGA BOOGA");
for (int i = 0; i < numThreads; i++) {
pthread_join(tid[i], NULL);
printf("Thread %10x joined\n", tid[i]);
fflush(stdout);
}
printf("All Four Threads have exited using join(), exiting program....\n");
fflush(stdout);
exit(EXIT_SUCCESS);
return validateRows(x) + validateCols(x) + validateSubGrids(x); // if all true = valid 9x9, else = not valid 9x9
// return validateSubGrids(x);
}
Pthreads 需要 void* func (void*)
形式的回调函数,句号。您不能发明自己的函数格式并期望它起作用。
此外 vr(x)
等参数是 函数调用 - 你调用函数一次然后使用它的结果告诉 pthread_create
它是一个指针到回调函数,它不是 - 这只是胡说八道。
此外,具有 return 类型的函数必须始终 return
某些内容。
所有这些问题都可以通过正确配置编译器在早期避免,因此它会在遇到明显的错误和无效的 C 时给出错误,请参阅 What compiler options are recommended for beginners learning C? 正确使用函数是非常基础的东西,你在进入更高级的主题之前需要掌握,例如 multi-threading.
正确使用,正如友情所说 man:
void* vr (void* x) {
validateRows(x);
return NULL;
}
...
pthread_create(&tid[i], NULL, vr, x);
我不确定你的代码是否编译,但如果编译成功,那么会发生什么:当程序 运行s,然后在 pthread_create() 函数中,它将调用你的函数vr() 并使用 vr() 的 return 值作为指向创建线程时应调用的函数的指针。
但是vr()没有return任何值,但在这里并不重要。
任何函数的return值根据系统存储在某处(寄存器等)。假设 return 值存储在名为 A 的寄存器中。因此,将调用 vr(x),然后读取寄存器 A 中的值,然后代码将假定该值是指向应该调用的函数。但是 A 可以有任何值(因为函数 vr(x) 没有 return 任何值,因此它没有更新 A)- 0x0、0x1、0x75745 等。而且大多数情况下这将是一个无效地址(可能会指向受限内存区域,或只读内存等)因此硬件会引发内存访问冲突 interrupt/signal,然后导致分段错误。
运行下面的代码你就明白我在说什么了
#include <stdio.h>
#include <pthread.h>
void *f(void *g)
{
printf("Called f().\n");
}
void *x(void *v)
{
printf("Called x().\n");
return (void *)(f);
}
int main(void)
{
pthread_t pt;
pthread_create(&pt, NULL, x((void *)5), NULL);
// join pthread.
pthread_join(pt, NULL);
return 0;
}
当您 运行 上面的代码时,函数 x() 和 f() 都会被调用。
输出将是:
调用了 x()。 调用了 f()。