如何用C中的pthread替换顺序操作?

时间:2017-03-01 17:09:17

标签: c multithreading pthreads

我有一个函数来计算一个更大的字符串的数字子字符串(使用更小的字符串来匹配),我试图用pthreads替换这个序列,从而在没有循环的情况下同时处理整个事物。

我正在寻找能够做到这一点的原则。 到目前为止我所做的是创建一个pthread_t动态数组,这个数组的数量与字符数相同。更大的字符串,我正在为线程分配计算子字符串的函数,我想我几乎要把它弄清楚,我只需要推进就可以了解它。

pthreads.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>


#define MAX 1024

int total = 0;
int n1,n2;
int num_thr;
int *num_threads;
char *s1,*s2;
FILE *fp;

int readf(FILE *fp)
{
    if((fp=fopen("strings.txt", "r"))==NULL){
        printf("ERROR: can't open string.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)-1;  /*length of s1*/

    n2=strlen(s2)-1; /*length of s2*/
    num_thr=n1;
    printf("String 1 len = %d\n",n1);

    if(s1==NULL || s2==NULL || n1<n2)  /*when error exit*/
        return -1;
}

void *num_substring(void *vari);
void *num_substring(void *vari)
{
    int i,j,k;
    int count;

    for (i = 0; i <= (n1-n2); i++){   
        count=0;
        for(j = i,k = 0; k < n2; j++,k++){  /*search for the next string of size of n2*/  
            if (*(s1+j)!=*(s2+k)){
                break;
            }
            else
                count++;
            if(count==n2)    
                total++;        /*find a substring in this step*/                          
        }
    }
    printf("total= %d\n",total);
    //return total;
}








int main (int argc, char *argv[])
{

int count;

    readf(fp);

    printf("The number of substrings is: %d\n", count);



int i, ret=-1;
char *msg1= "a thread";
pthread_t * thread_arr = malloc(sizeof(pthread_t)*num_thr);
printf("num threads inside main = %d\n",num_thr);
for (i = 0; i < num_thr; i++) {

    ret = pthread_create(&thread_arr[i], NULL, num_substring, (void *) msg1);

    if(ret != 0) {
        printf ("Create pthread %d error!\n",i);
        exit (1);
    }
     printf("Main function thread %d created\n",i);
}

for (i=0;i < num_thr; i++){
pthread_join(thread_arr[i], NULL);
}




return 0;
} 

此程序的正确输出必须为4,因为ab在另一个字符串中出现4次,因此子字符串的数量必须等于4:

string.txt内容:

abcdabsufsoababuosufba

AB

我的输出并非完全错误,因为它最初显示4然后它开始递增(这不是我想要的所有我想要的是4)但是,它仍然没有完成因为我没有用pthreads替换循环数组(pthread_arr)是我猜测的最后一步,这是我的输出:

String 1 len = 22
The number of substrings is: 10219508
num threads inside main = 22
Main function thread 0 created
Main function thread 1 created
Main function thread 2 created
Main function thread 3 created
total= 4 // this is the correct number of substrings
total= 8
total= 12
Main function thread 4 created
total= 20
total= 16
Main function thread 5 created
Main function thread 6 created
total= 24
Main function thread 7 created
total= 28
Main function thread 8 created
total= 36
total= 32
Main function thread 9 created
total= 40
Main function thread 10 created
total= 44
Main function thread 11 created
Main function thread 12 created
total= 48
total= 52
Main function thread 13 created
total= 56
Main function thread 14 created
total= 60
Main function thread 15 created
Main function thread 16 created
Main function thread 17 created
Main function thread 18 created
Main function thread 19 created
Main function thread 20 created
Main function thread 21 created
total= 64
total= 68
total= 84
total= 76
total= 72
total= 80
total= 88

1 个答案:

答案 0 :(得分:2)

你非常接近,但有一些错误。

  1. 每个帖子都在扫描整个s1,而不只是扫描子字符串。
  2. main应传递一个参数,指示s1
  3. 中子字符串的起始偏移量
  4. 线程函数中只需要一个[或者需要]的循环。
  5. 每个线程都在递增全局total [没有线程锁定]。最好将值作为线程的返回值传回
  6. 因为s1中的每个字符都有一个线程,所以线程会将0或1视为计数[仅]。
  7. 我修复了你的代码[请原谅无偿的风格清理]:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    
    #define MAX 1024
    
    int n1;
    int n2;
    int num_thr;
    int *num_threads;
    char *s1;
    char *s2;
    FILE *fp;
    
    int
    readf(FILE * fp)
    {
        char *cp;
    
        if ((fp = fopen("strings.txt", "r")) == NULL) {
            printf("ERROR: can't open string.txt!\n");
            return 0;
        }
    
        if (s1 == NULL)
            s1 = (char *) malloc(sizeof(char) * MAX);
        if (s1 == NULL) {
            printf("ERROR: Out of memory!\n");
            return -1;
        }
    
        if (s2 == NULL)
            s2 = (char *) malloc(sizeof(char) * MAX);
        if (s1 == NULL) {
            printf("ERROR: Out of memory\n");
            return -1;
        }
    
        /* read s1 s2 from the file */
        cp = fgets(s1, MAX, fp);
        if (cp == NULL)
            return -1;
    
        cp = fgets(s2, MAX, fp);
        if (cp == NULL)
            return -1;
    
        n1 = strlen(s1) - 1;                /* length of s1 */
        n2 = strlen(s2) - 1;                /* length of s2 */
    
        num_thr = n1;
        printf("String 1 len = %d\n", n1);
    
        if (n1 < n2)
            return -1;
    
        return 0;
    }
    
    void *
    num_substring(void *vari)
    {
        int i;
        long subtotal;
    
        subtotal = 0;
    
    #if 0
        int count;
        int j;
        int k;
        for (int i = 0; i <= (n1 - n2); i++) {
            count = 0;
            /* search for the next string of size of n2 */
            for (int j = i, k = 0; k < n2; j++, k++) {
                if (*(s1 + j) != *(s2 + k)) {
                    break;
                }
                else
                    count++;
                if (count == n2)
                    subtotal++;             /* find a substring in this step */
            }
        }
    #else
        int t = (long) vari;
        char *cp = &s1[t];
        subtotal = 1;
        for (i = 0; i < n2; i++) {
            //printf("t%d: TRY: %c %c\n",t,cp[i],s2[i]);
            if (cp[i] != s2[i]) {
                subtotal = 0;
                break;
            }
        }
    #endif
    
        //printf("t%d: subtotal= %ld\n", subtotal);
    
        return (void *) subtotal;
    }
    
    int
    main(int argc, char *argv[])
    {
        int total = 0;
        void *ptr;
    
        //int count;
    
        readf(fp);
    
        //printf("The number of substrings is: %d\n", count);
    
        long i;
        int ret = -1;
        //char *msg1 = "a thread";
        pthread_t *thread_arr = malloc(sizeof(pthread_t) * num_thr);
    
        printf("num threads inside main = %d\n", num_thr);
        for (i = 0; i < num_thr; i++) {
    #if 0
            ret = pthread_create(&thread_arr[i], NULL, num_substring,(void *) msg1);
    #else
            ret = pthread_create(&thread_arr[i], NULL, num_substring,(void *) i);
    #endif
    
            if (ret != 0) {
                printf("Create pthread %ld error!\n", i);
                exit(1);
            }
            printf("Main function thread %ld created\n", i);
        }
    
        total = 0;
        for (i = 0; i < num_thr; i++) {
            pthread_join(thread_arr[i], &ptr);
            total += (long) ptr;
        }
    
        printf("TOTAL: %d\n",total);
    
        return 0;
    }