multithreading and dualcore

Started by
21 comments, last by Washu 17 years, 10 months ago
Hello! I want to creat a linkedlist of all elements to draw with multithreading! For updating the list, the main thread copys the element, overwrites it with the new data and then just sets the pointer of the previous to the new one(so no problem there, because the other is just reading the list) The Problem is now: can it occur(on a dual core) that both threads(cores) access the pointer(the adress stored by the pointer, not the data pointed to) at the same time? so, while one thread is reading it, the other is writing to it! wouldnt the adress then be corrupted? thx for answers
"be fair! ... always"Zeusel
Advertisement
Yep, this is a general problem for any multi-threaded programming, not just for software running on dual-core CPUs. There's a whole family of such issues known as synchronization problems.

The solution is to lock the list when it is being updated or accessed so that other threads can't screw things up. The simplest method is probably to use a mutex.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

They can access the same pointer at the same time, but since writing only takes one cycle (I think), the data won't be corrupted. You don't have to worry about it.
What you do have to worry about is making sure two threads don't try to write to the same data, causing it to get "out of sync".

Also, your method won't work when you remove elements from the list. What if thread 1 is looking at the last node of the list, and thread 2 then gets scheduled in and deletes the last node? When thread 1 gets scheduled back in, it's looking at invalid memory.
the deleting is also rather simple! i just have to use a second pointer for the deletelist and a variable "used"! mutex could also work, have to think about that one!

1) my list has an order! which is rather useful to my idea! :)
2) when no longer used the object is added to the deletelist! (also sorted)
3) when deleting, the objects are deleted until the object with "used" variable is set!(from front to back, same direction in which reading occurs)

There should be no problem because the elements before the "used" object are no longer pointed to by the main list, and thus can no longer be read by thread 2! if you want a graphic of the situation...ask, but it looks awful
"be fair! ... always"Zeusel
Quote:I want to creat a linkedlist of all elements to draw with multithreading!

Can you elaborate on this please?
Are you using mutiple threads to render or are there multiple threads updating objects states?
Quote:I want to creat a linkedlist of all elements to draw with multithreading!

Can you elaborate on this please?
Are you using mutiple threads to render or are there multiple threads updating objects states?
2 Threads: one updates the objects(linkedlist consists of object) and the other one renders them
"be fair! ... always"Zeusel
You can do this by having two linked lists.
The rendering thread starts at the head of one list (a pointer to one of your objects) and runs through it rendering every element like you would expect. The other thread works on the other list, and when it is ready, just changes the value of the head pointer that the rendering thread uses to the new list - since this is one op like Evil said, you can do it anytime. In the next rendering pass, the rendering thread will now be using the newly changed list.
You have to make sure that the second thread doesn't work on the list that the rendering thread is currently rendering though. I think I avoided this by having another variable that the rendering thread sets at the beginning of a render so that the other thread will know when the old list is safe to alter. In this way the rendering thread can run at full speed, and the data changing thread will be the only one that has to wait; I wouldn't want to have the rendering thread waiting on a mutex, that will likely cause the frame rate to stutter noticeably.
Hope that all makes sense.

Edit: I should add that there are no mutexes necessary, the data changing thread can just sleep(1) if the rendering thread has not yet started another pass since the list head changed.
Quote:Original post by Evil Steve
They can access the same pointer at the same time, but since writing only takes one cycle (I think), the data won't be corrupted. You don't have to worry about it.

If you only plan to write a single 32-bit value, yes.

And it might still be a problem if you access the pointer more than once, and expect it to still be the same value.
The most standard method would be to lock the data, so only one thread can modify the state of the list at once.

Ie:
Render thread walks up to the list, locks it, takes the front element off of the list, unlocks the list, and then goes off and renders that element.

The producer, when she wants to add data to the list, locks the list, appends the element, and unlocks the list.

The above operations can involve multiple elements at once for efficiency. (ie, the renderer can lock; take multiple elements; unlock; render them;, and the producer can make multiple elements, lock, add the elements to the list, unlock.)

An alternative is implementing a "lock-free" list or queue. This isn't nearly as easy as you think, unless you have done it before.

Multithreaded programming is quite often much harder than you think it is. It is usually best to stress correctness of your code. One large problem with multithreaded code is that the number of time slices each thread gets is non deterministic (it depends on system load amoung other factors) -- so even if your code works in a test run, it may still have bugs, and it may generate system instability months down the line.

This topic is closed to new replies.

Advertisement