Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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多线程:竞争条件场景_C_Multithreading_Semaphore_Volatile - Fatal编程技术网

C多线程:竞争条件场景

C多线程:竞争条件场景,c,multithreading,semaphore,volatile,C,Multithreading,Semaphore,Volatile,在下面的代码中,我只是想看看是否能够从每个线程向数组中插入一个元素。它正在按预期工作。但我想知道,在什么情况下,这里会有比赛条件。我真的需要volatile还是信号量?我尝试删除信号量和易失性关键字,但仍然有效。我想在这里归纳并看到一个竞争条件场景。在同一行上,我可以从每个线程创建一个节点并将所有节点放入一个链表中吗?这些都是想象中的情景 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #

在下面的代码中,我只是想看看是否能够从每个线程向数组中插入一个元素。它正在按预期工作。但我想知道,在什么情况下,这里会有比赛条件。我真的需要volatile还是信号量?我尝试删除信号量和易失性关键字,但仍然有效。我想在这里归纳并看到一个竞争条件场景。在同一行上,我可以从每个线程创建一个节点并将所有节点放入一个链表中吗?这些都是想象中的情景

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include "small_appl.h"

void * thread_func(void * arg);

int itr=0;
volatile int idx=0; //array index variable
sem_t sem1;
int arr_th[5];      //array where each thread will insert an element

int func_pointed(int a,int num_t)
{
    pthread_t arr_thr[num_t];
    int iter;
     //create threads
     for(iter=0;iter<num_t;iter++)
     {
        pthread_create(&arr_thr[iter],NULL,thread_func,(void *)a);
     }

     for (iter=0;iter<num_t;iter++)
     {
         pthread_join(arr_thr[iter],NULL);
     }
}

int main(void)
{
    int ip1=5,ip2=10,rev;

    rev=sem_init(&sem1,0,0);
    s_type dev_s={
                    .f_ptr=func_pointed,
                    .str="Diwakar",
                    .val=5
                 };

    //initialize semaphore to 1
    sem_post(&sem1);    

    func_aux(ip1,dev_s);

    for(rev=0;rev<5;rev++)
    {
    printf("array : %d    ",arr_th[rev]);
    }

}

void * thread_func(void * arg)
{
    sem_wait(&sem1);
    printf("Got sema\n");
    arr_th[idx]=itr;
    idx++; itr++;
    printf("Releasing sema\n");
    sem_post(&sem1);

    sleep(5);
}
#包括
#包括
#包括
#包括
#包括“小型应用程序h”
void*thread_func(void*arg);
int-itr=0;
volatile int idx=0//数组索引变量
sem_t sem1;
国际协议[5]//数组,其中每个线程将插入一个元素
int func_pointed(int a,int num_t)
{
pthread_t arr_thr[num_t];
国际热核实验堆;
//创建线程

为了(iter=0;iter创建或模拟一个线程覆盖另一个线程所做的工作的情况,然后移除信号量并战略性地放置睡眠,如下所示:

void * thread_func(void * arg)
{
    //sem_wait(&sem1);
    //printf("Got sema\n");
    arr_th[idx]=itr;
    // print arr_th[idx]
    sleep(5);     <<== gives the threads more of a chance to wipe-out each other
    // print arr_th[idx]
    idx++; itr++;
    //printf("Releasing sema\n");
    //sem_post(&sem1);

    sleep(5);
}
void*线程函数(void*arg)
{
//sem_wait(&sem1);
//printf(“获得语义\n”);
arr_th[idx]=itr;
//打印阵列[idx]

sleep(5);volatile指示编译器变量可以随时更改。这意味着对变量的每次引用都必须导致从内存中读取(而不是在寄存器中重用该值的副本)

如果
volatile
关键字不存在,编译器可能会将变量读入寄存器一次,并检查它是否为0和1

如果在主程序中等待idx变量变成这样的特定值,则应使其
为volatile

while(idx==10);
Volatile不能保证线程安全,这是另一个问题。事实上,由于您保护了这段代码,您不希望idx从一次读取更改为下一次读取,因此您不需要Volatile


如果您想产生竞争条件(检测代码被分割的部分),我建议设置两个值,在两条单独的指令中递增,并在一个连续的while循环中执行此操作(无睡眠!如果睡眠,则减少关键部分被分割的机会).在主循环中,持续检查值是否相等(同样,无休眠)。如果它们不相等,则两段代码中的一段被拆分。另外,请查看程序集,以确保编译器没有优化某些内容。

在C中,
volatile
并不是您认为它的意思。特别是,它与原子变量或与内存同步有关的任何内容不同。竞争条件不是易于生成。C中的volatile只是告诉编译器不要为此变量进行优化,而不是为了多线程目的。您不需要在代码中的任何地方使用volatile。您也不需要“需要”信号量,因为您真正使用它的只是一个互斥体(如果您扔掉信号量,您确实需要互斥体)。你能给我一些提示,说明序列化关键部分意味着什么吗?@DiwakarSharma,基本思想是在任何时候只允许一个线程运行它的一小部分指令。记住,所有线程通常运行相同的代码,但它的某些部分只能允许一个线程执行。搜索互斥或语义还有对系统函数的调用可以实现这一点。但是,如果您了解信号量的概念,那么您可以编写自己的序列化代码。要解释更多内容,需要一章,但要了解信号量的概念以及如何使用C代码实现。
while(idx==10);