Pthread 程序在代码块和 Linux 内核上打印不同的值

Pthread program printing different values on Codeblocks and Linux Kernel

我正在处理以下 pthread 程序,它查找 string2 中 string1 中的子串数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#define NUM_THREADS 4
#define MAX 1024

int n1,n2,i;
char *s1,*s2;
FILE *fp;

char *substring(char *string, int position, int length);
void *occurrence();


int readf(FILE *fp)
{
    if((fp=fopen("strings.txt", "r"))==NULL){
        printf("ERROR: can't open strings.txt!\n");
        return 0;
    }
    s1=(char *)malloc(sizeof(char)*MAX);
    if(s1==NULL){
        printf("ERROR: Out of memory!\n");
        return -1;
    }
    s2=(char *)malloc(sizeof(char)*MAX);
    if(s1==NULL){
        printf("ERROR: Out of memory\n");
        return -1;
    }
    /*read s1 s2 from the file*/
    s1=fgets(s1, MAX, fp);
    s2=fgets(s2, MAX, fp);
    n1=strlen(s1);  /*length of s1*/
    n2=strlen(s2)-1; /*length of s2*/
    if(s1==NULL || s2==NULL || n1<n2)  /*when error exit*/
        return -1;
    return 0;
}

int main(void)
{
    pthread_t tid;
    pthread_create(&tid, NULL, occurrence, NULL);
    pthread_join(tid, NULL);
    exit(0);
}

char *substring(char *string, int position, int length)
{
    char *pointer;
    int c;

    pointer = malloc(length+1);

    if (pointer == NULL)
    {
        printf("Unable to allocate memory.\n");
        exit(1);
    }

    for (c = 0 ; c < length ; c++)
    {
        *(pointer+c) = *(string+position-1);
        string++;
    }

    *(pointer+c) = '[=11=]';

    return pointer;
}

void* occurrence()
{
    char *string1;
    char *string2;
    char *new_str;
    int counter=0;
    readf(fp);

    string1 = s1;
    string2 = s2;
    new_str = malloc(200);
    for(i=1;i<=strlen(string1);i++)
    {
        new_str = substring(string1,i,strlen(string2));
        if(strcmp(new_str, string2)==0)
        {
            counter++;
        }
    }
    printf("The number of substrings is: %d \n",counter);
    return 0;
}

当我在代码块上编译它时,它打印出正确数量的子字符串。然而,当我在 Linux 内核上编译它时,它总是打印 1 作为子字符串的数量,即使有不止一个。例如,第一行有 abdeabjhab 并且第二行有 abstrings.txt 文件应该打印 3,因为有 3第一行 ab 的实例。我的 Linux 内核打印 1。是否有特定的方法可以编译它以打印正确的值? 我目前正在使用 gcc -pthread substring.c -o substrings编译并 ./substrings 执行它。

这里有几个问题。

首先occurrence的签名是错误的;线程函数应将 void* 作为参数,并根据 pthread_create API 的要求将 return 和 void* 作为参数。所以应该是:

void *occurrence(void*);

void *occurrence(void arg*) {
    ...
    return NULL;
}

您的代码中还有其他几个问题。

  • 您正在将全局变量 fp 传递给 readf() 函数。为什么需要传递一个全局变量?

  • 您只阅读了前两行。如果文件包含更多行怎么办?

  • 为什么 s1s2 是全局的?您可以轻松地重写它以从 readf 传递回 occurrence。或者 occurrence 可以传递 readf 写入的变量。

  • 您没有使用 fclose 关闭文件。

  • 您只创建一个线程来完成工作,主线程只是等待它。所以这里真的不需要线程。您还不如让主线程完成工作,而不用去打扰线程。

  • 这里为什么要减:n2=strlen(s2)-1; /*length of s2*/。 如果 s1s2 的长度相同怎么办? "abc" 不是 "abc" 的子串吗?

你的子串计数不正确的实际问题可能是因为fgets()读入了换行符,因此子串匹配失败。

要删除换行符,您可以在阅读 s1s2:

后在 readf 函数中执行
char *p = strchr(s1, '\n');
if (p) *p = 0;
p = strchr(s2, '\n');
if (p) *p = 0;

这应该可以解决眼前的问题。但是还有很多地方可以改进。