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 并且第二行有 ab 的 strings.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()
函数。为什么需要传递一个全局变量?
您只阅读了前两行。如果文件包含更多行怎么办?
为什么 s1
和 s2
是全局的?您可以轻松地重写它以从 readf
传递回 occurrence
。或者 occurrence
可以传递 readf
写入的变量。
您没有使用 fclose
关闭文件。
您只创建一个线程来完成工作,主线程只是等待它。所以这里真的不需要线程。您还不如让主线程完成工作,而不用去打扰线程。
这里为什么要减:n2=strlen(s2)-1; /*length of s2*/
。
如果 s1
和 s2
的长度相同怎么办? "abc"
不是 "abc"
的子串吗?
你的子串计数不正确的实际问题可能是因为fgets()
读入了换行符,因此子串匹配失败。
要删除换行符,您可以在阅读 s1
和 s2
:
后在 readf
函数中执行
char *p = strchr(s1, '\n');
if (p) *p = 0;
p = strchr(s2, '\n');
if (p) *p = 0;
这应该可以解决眼前的问题。但是还有很多地方可以改进。
我正在处理以下 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 并且第二行有 ab 的 strings.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()
函数。为什么需要传递一个全局变量?您只阅读了前两行。如果文件包含更多行怎么办?
为什么
s1
和s2
是全局的?您可以轻松地重写它以从readf
传递回occurrence
。或者occurrence
可以传递readf
写入的变量。您没有使用
fclose
关闭文件。您只创建一个线程来完成工作,主线程只是等待它。所以这里真的不需要线程。您还不如让主线程完成工作,而不用去打扰线程。
这里为什么要减:
n2=strlen(s2)-1; /*length of s2*/
。 如果s1
和s2
的长度相同怎么办?"abc"
不是"abc"
的子串吗?
你的子串计数不正确的实际问题可能是因为fgets()
读入了换行符,因此子串匹配失败。
要删除换行符,您可以在阅读 s1
和 s2
:
readf
函数中执行
char *p = strchr(s1, '\n');
if (p) *p = 0;
p = strchr(s2, '\n');
if (p) *p = 0;
这应该可以解决眼前的问题。但是还有很多地方可以改进。