简体   繁体   English

两个线程从相同的 function RT Linux 给出不同的 output

[英]Two threads giving different output from same function RT Linux

i have a 2 threads and a function, im calling the same function "no_elements()" from two threads the function is我有 2 个线程和一个 function,我从两个线程调用相同的 function“no_elements()”,function 是

int front = -1, rear = -1;
int no_elements()
{

int q_size = 0;

if (front == 0)
{
    
    q_size = rear + 1;

    return q_size;
}
else if (front != 0 && rear != 0)
{
    
    q_size = (rear - front) + 1;
    return q_size;
}
else if (rear == 0 && front != 0)
{
    
    q_size = (SIZE - front)+1;
    return q_size;
}
else if (rear == -1 || front == -1 )
    {
        q_size = 0;
        printf("empty---- ---------------------------------------------------------------------");
        return q_size;
    }

}

and the two threads call the same function并且两个线程调用相同的 function

iret1 = pthread_create(&thread1, NULL, producer,(void*) message1);
iret2 = pthread_create(&thread2, NULL, consumer,(void*) message2);

Producer and consumer functions are生产者和消费者函数是

void *producer(void *ptr) // enque function
{
char *message;
printf("%s \n", message);
enQueue(data);
printf("No of elements%d\n",no_elements());
}

second function is第二个 function 是

void *consumer(void *ptr) // enque function
{
char *message;
printf("%s \n", message);
printf("No of elements%d\n",no_elements());
}

and enqueue function is并入队 function 是

void enQueue(double *element)
{

 if (isFull())
 printf("\n Queue is full!! \n");
 else
 {

     int i=0;
    if (front == -1)
{
    front = 0;
}
rear = (rear + 1) % SIZE;

memcpy(items[rear].value, element, sizeof (items[rear].value)); // better: sizeof struct

printf("front is  %d--",front);
printf("rear is  %d\n",rear);


 }
}

but the first thread gives correct result and second one gives the initialized value of front and rear.但是第一个线程给出了正确的结果,第二个给出了前后的初始化值。

here front and rear are global variables, they are manipulated in first thread by enqueue function, then i call the function no_elements() which returns a value which is correct.这里前面和后面是全局变量,它们在第一个线程中由入队 function 操作,然后我调用 function no_elements() 返回一个正确的值。

but at the same time the second thread returns the initialized values of front and rear但同时第二个线程返回了前后端的初始化值

what can be wrong?有什么问题?

can this be done?可以这样做吗?

   void enQueue(double *element)
   {
    pthread_mutex_lock(&lock);

   if (isFull())
    printf("\n Queue is full!! \n");
    else
   {

   int i=0;
   if (front == -1)
   {
  front = 0;
  }
  rear = (rear + 1) % SIZE;

 memcpy(items[rear].value, element, sizeof (items[rear].value)); // better: 
 sizeof struct

printf("front is  %d--",front);
printf("rear is  %d\n",rear);


 }
 pthread_mutex_unlock(&lock);
}

Calling your no_elements() function and / or your enqueue() function from multiple threads that are concurrently alive produces several data races, therefore the behavior of your program is undefined.从同时处于活动状态的多个线程调用no_elements() function 和/或enqueue() function 会产生多个数据竞争,因此程序的行为是未定义的。 The data races arise from those functions accessing shared variables front , rear , and items (at least) without any kind of synchronization, given that some of the accesses are writes.考虑到某些访问是写入,数据竞争源于那些访问共享变量frontrearitems (至少)而没有任何同步的函数。 You must protect shared variables against concurrent access, typically by creating a mutex that each thread must successfully lock before accessing those variables.您必须保护共享变量免受并发访问,通常通过创建每个线程在访问这些变量之前必须成功锁定的互斥锁。 Threads must also be sure to unlock the mutex at some point after access in order to afford other threads the opportunity to lock it.线程还必须确保在访问后的某个时间点解锁互斥锁,以便为其他线程提供锁定它的机会。

The results of accessing an object while another thread is, or might be, accessing it are undefined.访问 object 而另一个线程正在或可能正在访问它的结果是未定义的。 You have this problem with both front and read .你在frontread都有这个问题。 So the results of your program are undefined and may be totally unpredictable.因此,您的程序的结果是未定义的,并且可能完全无法预测。

It is the responsibility of the programmer to ensure that threads do not access the same object at the same time.程序员有责任确保线程不会同时访问同一个 object。 There are lots of tools for this purpose and the first version of enQueue uses none of them.为此目的有很多工具,而enQueue的第一个版本没有使用它们。

When you call pthread_create, what actually executes next is indeterminate.当您调用 pthread_create 时,接下来实际执行的内容是不确定的。 From the pthread_create man page:pthread_create手册页:

Unless real-time scheduling policies are being employed, after a call to pthread_create(), it is indeterminate which thread—the caller or the new thread—will next execute.除非采用实时调度策略,否则在调用 pthread_create() 之后,不确定哪个线程(调用者或新线程)接下来将执行。

If you extend this to your scenario, where you are creating two threads, it's even more indeterminate what the order of execution is.如果将其扩展到创建两个线程的场景,则执行顺序更加不确定。 In other words, you have no way of knowing whether producer or consumer will start executing first.换句话说,您无法知道生产者消费者将首先开始执行。

You can fix this by rewriting the pthread code like this:您可以通过像这样重写 pthread 代码来解决此问题:

iret1 = pthread_create(&thread1, NULL, producer,(void*) message1);
pthread_join(&thread1, NULL);
iret2 = pthread_create(&thread2, NULL, consumer,(void*) message2);
pthread_join(&thread2, NULL);

EDIT: additional note - if you need the threads to be created and run simultaneously, then you can use a mechanism like a semaphore to delay the consumer thread before the producer thread.编辑:附加说明 - 如果您需要同时创建和运行线程,那么您可以使用信号量等机制在生产者线程之前延迟消费者线程。 I don't think that a mutex, while absolutely correct in protecting the sanity of your variables, will still gaurantee the order of thread execution.我认为互斥锁虽然在保护变量的完整性方面绝对正确,但仍不能保证线程执行的顺序。 The only other way is by assigning priorities to the tasks..唯一的另一种方法是为任务分配优先级..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有多个线程的程序总是给出相同的 output - Program with multiple threads always giving same output 生产者使用者同步使用两个线程提供异常的串行输出 - Producer consumer sync using two threads giving unsual serial output gettid() 为两个不同的线程返回相同的值? - gettid() returning the same value for two different threads? 在同一个C程序中的两个线程之间发送UDP消息(Linux) - Sending UDP messages between two threads in the same C program (Linux) 从不同线程调用相同的 function 时解决 errno 的机制是什么 - What is the mechanism to address errno when calling same function from different threads 3 个不同的函数根据 C 中的变量类型提供相同的输出 - 3 different functions giving the same output depending on variable type in C 两个几乎完全相同的程序,但输出不同 - Two almost exactly the same programs but different output snprintf给出不同的输出 - snprintf giving different output 从两个不同的线程在两个不同的索引处写入浮点数组是否安全? - Is writing to an array of floats from 2 different threads at two different indexes safe? Function 添加两个分数和 output 十进制只给出 0 - Function to add two fractions and output decimal only giving 0
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM