Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
彼得森';C中线程并发(段故障)的s算法_C_Multithreading_Algorithm - Fatal编程技术网

彼得森';C中线程并发(段故障)的s算法

彼得森';C中线程并发(段故障)的s算法,c,multithreading,algorithm,C,Multithreading,Algorithm,嘿,伙计们,我正在用C实现Peterson的算法。我有两个函数,将由创建的线程执行,一个是给变量加1,另一个是给同一个变量减去1 程序接收int类型的参数,该整数是我想要创建的线程数的平方根,例如,如果我在终端类型中执行它 /算法10,将创建10*10(10000)个线程 如果y类型小于170作为参数,程序运行正常(将创建28900个线程),但是如果我想创建更多的线程,我得到了一个段错误,尝试使用“long long int”变量,但不是这样 有一个名为“cont”的计数器,每次cont达到10

嘿,伙计们,我正在用C实现Peterson的算法。我有两个函数,将由创建的线程执行,一个是给变量加1,另一个是给同一个变量减去1

程序接收int类型的参数,该整数是我想要创建的线程数的平方根,例如,如果我在终端类型中执行它 /算法10,将创建10*10(10000)个线程

如果y类型小于170作为参数,程序运行正常(将创建28900个线程),但是如果我想创建更多的线程,我得到了一个段错误,尝试使用“long long int”变量,但不是这样

有一个名为“cont”的计数器,每次cont达到10000时都会打印变量。 变量的最后一个结果还有另一个打印,它应该始终为0,因为n个线程加1,n个线程减1

我想知道为什么会出现段错误,要创建的线程是否有限制,或者代码中是否有错误

我使用下一个命令运行它,只使用一个处理器,因为Peterson的算法只能在单处理器系统上完美工作:

taskset -c 0 ./alg3 100
代码如下:

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




long int n;
long int var = 0;
long int cont = 1;
int flag[] = {0, 0};
int turn = 0;

void* sum(void* data) {
    //int n = *((int*)data); 
    int i;

    turn = 2;
    flag[0] = 1;
    while (turn == 2 && flag[1]);
    cont++;
    var += 1;
    if (cont == 10000) {
        printf("varsum=%ld\n", var);
        cont = 1;
    }

    flag[0] = 0;
}

void* rest(void* data) {
    //int n = *((int*)data); 
    int i;
    turn = 1;
    flag[1] = 1;
    while (turn == 1 && flag[0]);
    cont++;
    var -= 1;
    if (cont == 10000) {
        printf("varres=%ld\n", var);
        cont = 1;
    }

    flag[1] = 0;

}

main(int argc, char *argv[]) {
    long int i;
    n = atoi(argv[1]);
    n *= n; //n*n is the actual number of threads that will be created

    pthread_t tid[n];


    for (i = 0; i < n; i++) {
        pthread_create(&tid[i], NULL, sum, NULL);
        //cont++;

    }
    for (i = 0; i < n; i++)
        pthread_join(tid[i], NULL);

    for (i = 0; i < n; i++) {
        pthread_create(&tid[i], NULL, rest, NULL);
        //cont++;

    }
    for (i = 0; i < n; i++)
        pthread_join(tid[i], NULL);

    printf("main() reporting that all %ld threads have terminated\n", i);
    printf("variable=%ld\n", var);

} /* main */
#包括
#包括
#包括
长整数n;
长整型var=0;
长整数cont=1;
int标志[]={0,0};
整圈=0;
无效*总和(无效*数据){
//int n=*((int*)数据);
int i;
匝数=2;
标志[0]=1;
while(turn==2&&flag[1]);
cont++;
var+=1;
如果(续==10000){
printf(“varsum=%ld\n”,var);
cont=1;
}
标志[0]=0;
}
作废*剩余(作废*数据){
//int n=*((int*)数据);
int i;
圈数=1;
标志[1]=1;
while(turn==1&&flag[0]);
cont++;
var-=1;
如果(续==10000){
printf(“varres=%ld\n”,var);
cont=1;
}
标志[1]=0;
}
main(int argc,char*argv[]){
long int i;
n=atoi(argv[1]);
n*=n;//n*n是将创建的实际线程数
pthread_t tid[n];
对于(i=0;i
至少在
pthread\u create()
中添加错误检查,以避免将无效的
pthread\u t
变量传递到
pthread\u join()

int main(int弧,字符**argv)
{
...
pthread_t tid[n];
int结果[n];
对于(i=0;i


也要始终保护对写入的变量的并发访问,
count
此处。为此,请使用
pthread\u mutex\u t
变量。

首先,当然创建线程是有限制的。这取决于每个线程和硬件的堆栈大小,详细信息建议谷歌。。。 段故障原因: 您没有检查函数pthread_create的返回值,当'n'足够大时,pthread_create将失败,然后pthread_join可以使用不存在的thread_t作为第一个输入参数。以下代码(与您的示例不同)可以测试您可以在中创建多少线程

int rc = 0, thread_num = 0;
    for (i = 0; i < n; i++) {
        rc = pthread_create(&tid[i], NULL, sum, NULL);
        if (rc)
        {
            printf("pthread_crate failed, thread number: %d, error code: %d\n", thread_num, rc);
        }
        thread_num++;
    }
    printf("created %d threads.\n", thread_num);
int rc=0,thread_num=0;
对于(i=0;i
段故障几乎总是意味着指针错误或数组索引不合理。添加打印输出,或在调试器下运行它,以确定段故障发生的位置,并从那里进行调试……编译器习惯于对代码重新排序以进行优化。此排序仅保证对顺序代码有效。您可能需要检查详细信息C的内存模型(IIRC,直到最近才真正有一个)为了防止无效的重新排序,你需要做的任何事情。我不知道C的当前状态,你可能需要特定于平台的扩展。我确信声明变量<代码> Value是不够的。正如Stest314所说,你可能会遇到指令重新排序的问题。使用互斥来实现Peterson有点忽略了重点。在这里使用原子可能更合适,尽管这当然会为新手打开很多新的机会来攻击自己。底线:并发编程不适合胆小的人。是的,实际上我意识到我不需要那么多线程做我想做的,谢谢你的回答:)
int rc = 0, thread_num = 0;
    for (i = 0; i < n; i++) {
        rc = pthread_create(&tid[i], NULL, sum, NULL);
        if (rc)
        {
            printf("pthread_crate failed, thread number: %d, error code: %d\n", thread_num, rc);
        }
        thread_num++;
    }
    printf("created %d threads.\n", thread_num);