Skip to content
Advertisement

pointer get wrong value in different thread

I am writing a piece of code to demonstrate the multi-threading share memory writing.

However, my code gets a strange 0xffffffff pointer I can’t make out why. I haven’t been writing cpp code for a while. please let me know if I get something wrong.

I compile with the command: g++ --std=c++11 shared_mem_multi_write.cpp -lpthread -g

I get error echoes like:

function base_ptr: 0x5eebff, src_ptr: 0x7f21a9c4e010, size: 6220800
function base_ptr: 0xffffffffffffffff, src_ptr: 0x7f21a9c4e010, size: 6220800
function base_ptr: 0xbdd7ff, src_ptr: 0x7f21a9c4e010, size: 6220800
function base_ptr: 0x23987ff, src_ptr: 0x7f21a9c4e010, size: 6220800
function base_ptr: 0x11cc3ff, src_ptr: 0x7f21a9c4e010, size: 6220800
function base_ptr: 0x17bafff, src_ptr: 0x7f21a9c4e010, size: 6220800
function base_ptr: 0x1da9bff, src_ptr: 0x7f21a9c4e010, size: 6220800
Segmentation fault (core dumped)

my os is CentOS Linux release 7.6.1810 (Core) gcc version 4.8.5 and the code is posted below:

#include <chrono>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <thread>
#include <vector>
#include <memory>

const size_t THREAD_CNT = 40;
const size_t FRAME_SIZE = 1920 * 1080 * 3;
const size_t SEG_SIZE = FRAME_SIZE * THREAD_CNT;

void func(char *base_ptr, char *src_ptr, size_t size)
{
    printf("function base_ptr: %p, src_ptr: %p, size: %un", base_ptr, src_ptr, size);
    while (1)
    {
        auto now = std::chrono::system_clock::now();
        memcpy(base_ptr, src_ptr, size);
        std::chrono::system_clock::time_point next_ts =
            now + std::chrono::milliseconds(42); // 24 frame per seconds => 42 ms per frame
        std::this_thread::sleep_until(next_ts);
    }
}

int main(int argc, char **argv)
{
    int shmkey = 666;
    int shmid;
    shmid = shmget(shmkey, SEG_SIZE, IPC_CREAT);
    char *src_ptr = new char[FRAME_SIZE];
    char *shmpointer = static_cast<char *>(shmat(shmid, nullptr, 0));
    std::vector<std::shared_ptr<std::thread>> t_vec;
    t_vec.reserve(THREAD_CNT);
    for (int i = 0; i < THREAD_CNT; ++i)
    {
        //t_vec[i] = std::thread(func, i * FRAME_SIZE + shmpointer, src_ptr, FRAME_SIZE);
        t_vec[i] = std::make_shared<std::thread>(func, i * FRAME_SIZE + shmpointer, src_ptr, FRAME_SIZE);
    }
    for (auto &&t : t_vec)
    {
        t->join();
    }
    return 0;
}

Advertisement

Answer

You forgot specify access rights for created SHM segment (http://man7.org/linux/man-pages/man2/shmget.2.html):

The value shmflg is composed of:

In addition to the above flags, the least significant 9 bits of shmflg specify the permissions granted to the owner, group, and others. These bits have the same format, and the same meaning, as the mode argument of open(2). Presently, execute permissions are not used by the system.

Change

shmid = shmget(shmkey, SEG_SIZE, IPC_CREAT);

into

shmid = shmget(shmkey, SEG_SIZE, IPC_CREAT | 0666);

It works for me now: https://wandbox.org/permlink/Am4r2GBvM7kSmpdO


Note that I use only a vector of threads (no shared pointers), as other suggested in comments. You can possibly reserve its space as well.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement