簡體   English   中英

如何在C中用pthread替換順序操作?

[英]How do I replace sequential operation with pthreads in C?

我有一個函數,它計算一個較大的字符串(使用較小的字符串進行匹配)的子字符串數,我試圖用pthreads替換此序列,從而同時處理整個過程而沒有循環。

我正在尋找可以做到這一點的原則。 到目前為止,我所做的是創建一個pthread_t動態數組,該數組的數量與chars的數量相同。 對於較大的字符串,我正在將計算子字符串的功能分配給線程,我想我幾乎可以理解了,我只需要向前推進就可以了。

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)替換循環。 iam猜測是所需的最后一步,這是我的輸出:

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. 每個線程都在掃描整個s1而不僅僅是子字符串。
  2. main應該傳遞一個參數,該參數指示s1字符串的起始偏移量
  3. [或希望]線程功能中僅需要一個循環。
  4. 每個線程正在增加全局total (沒有線程鎖定)。 最好將值作為線程的返回值傳回
  5. 因為s1每個字符都有一個線程,所以一個線程將看到0或1作為計數(僅)。

我已經修復了您的代碼[請原諒免費的樣式清理]:

#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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM