I'm trying to implement a counting semaphore in C++11. This is my trial...
#include <iostream>
#include <thread>
#include <mutex>
#include <future>
#include <vector>
using namespace std;
class Semaphore{
private:
int count;
condition_variable cv;
mutex mtx;
public:
Semaphore(int count_):count(count_){}
void take(){
unique_lock<mutex> lck(mtx);
while(count == 0)
cv.wait(lck);
count--;
cout << "Take\n";
}
void release(){
unique_lock<mutex> lck(mtx);
count++;
cout << "Release\n";
cv.notify_one();
}
};
int main() {
Semaphore sem(5);
vector<thread> threads;
for(int i = 0; i < 10; i++){
threads.push_back(thread(&Semaphore::release, sem));
}
for(int i = 0; i < 10; i++){
threads.push_back(thread(&Semaphore::release, sem));
}
for(int i = 0; i < threads.size(); i++)
threads[i].join();
return 0;
}
However, when compiling, it's failing with the following error...
note: 'Semaphore::Semaphore(Semaphore&&)' is implicitly deleted because the default definition would be ill-formed:
class Semaphore{
My best guess is that this is because of using condition_variable inside a class, which is neither copyable nor movable, so it causes a problem when it's passed as a parameter to std::thread. However, I've no idea how to fix that. Any clues?
Update:
This is the full error log...
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:55:0,
from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:39,
from /Users/emostafa/Desktop/cpp/A.cpp:2:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple: In instantiation of 'constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with _UHead = Semaphore; long unsigned int _Idx = 1ul; _Head = Semaphore]':
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:369:49: required from 'constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head>&&) [with long unsigned int _Idx = 1ul; _Head = Semaphore]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1162:12: required from 'struct std::__is_nt_constructible_impl<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&>'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:137:12: required from 'struct std::__and_<std::is_constructible<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&>, std::__is_nt_constructible_impl<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&> >'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1174:12: required from 'struct std::is_nothrow_constructible<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&>'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1205:12: required from 'struct std::__is_nothrow_move_constructible_impl<std::_Tuple_impl<1ul, Semaphore>, true>'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1211:12: required from 'struct std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, Semaphore> >'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:137:12: required from 'struct std::__and_<std::is_nothrow_move_constructible<std::_Mem_fn<void (Semaphore::*)()> >, std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, Semaphore> > >'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:218:7: required from 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head, _Tail ...>&&) [with long unsigned int _Idx = 0ul; _Head = std::_Mem_fn<void (Semaphore::*)()>; _Tail = {Semaphore}]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1559:41: required from 'typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<std::_Mem_fn<void (Semaphore::*)()>(Semaphore)>]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:142:59: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}]'
/Users/emostafa/Desktop/cpp/A.cpp:37:54: required from here
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:115:42: error: use of deleted function 'Semaphore::Semaphore(Semaphore&&)'
: _M_head_impl(std::forward<_UHead>(__h)) { }
^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: note: 'Semaphore::Semaphore(Semaphore&&)' is implicitly deleted because the default definition would be ill-formed:
class Semaphore{
^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::condition_variable::condition_variable(const std::condition_variable&)'
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/future:41:0,
from /Users/emostafa/Desktop/cpp/A.cpp:4:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/condition_variable:81:5: note: declared here
condition_variable(const condition_variable&) = delete;
^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::mutex::mutex(const std::mutex&)'
class Semaphore{
^
In file included from /Users/emostafa/Desktop/cpp/A.cpp:3:0:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/mutex:129:5: note: declared here
mutex(const mutex&) = delete;
^
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:55:0,
from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:39,
from /Users/emostafa/Desktop/cpp/A.cpp:2:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple: In instantiation of 'constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const _Head&) [with long unsigned int _Idx = 1ul; _Head = Semaphore]':
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:357:21: required from 'constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(const _Head&) [with long unsigned int _Idx = 1ul; _Head = Semaphore]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:206:44: required from 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 0ul; _Head = std::_Mem_fn<void (Semaphore::*)()>; _Tail = {Semaphore}]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:606:30: required from 'constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = std::_Mem_fn<void (Semaphore::*)()>; _T2 = Semaphore]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1510:72: required from 'std::_Bind_simple<_Callable(_Args ...)>::_Bind_simple(_Tp&&, _Up&& ...) [with _Tp = std::_Mem_fn<void (Semaphore::*)()>; _Up = {Semaphore&}; _Callable = std::_Mem_fn<void (Semaphore::*)()>; _Args = {Semaphore}]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1559:41: required from 'typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<std::_Mem_fn<void (Semaphore::*)()>(Semaphore)>]'
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:142:59: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}]'
/Users/emostafa/Desktop/cpp/A.cpp:37:54: required from here
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:108:25: error: use of deleted function 'Semaphore::Semaphore(const Semaphore&)'
: _M_head_impl(__h) { }
^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: note: 'Semaphore::Semaphore(const Semaphore&)' is implicitly deleted because the default definition would be ill-formed:
class Semaphore{
^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::condition_variable::condition_variable(const std::condition_variable&)'
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/future:41:0,
from /Users/emostafa/Desktop/cpp/A.cpp:4:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/condition_variable:81:5: note: declared here
condition_variable(const condition_variable&) = delete;
^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::mutex::mutex(const std::mutex&)'
class Semaphore{
^
In file included from /Users/emostafa/Desktop/cpp/A.cpp:3:0:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/mutex:129:5: note: declared here
mutex(const mutex&) = delete;
You're passing the sem object as a value to the thread constructor. This requires that it be copied, which is what the 'use of deleted function' refers to.
If you want a thread, task, async context, ... to have a reference to your semaphore, either pass it by std::ref(sem), or fall back to plain old pointers and pass it the address of: &sem.
Related
When compile my project, i got there errors, i have no ideas about this error
In file included from /home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/fmt/fmt.h:22:0,
from /home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/common.h:36,
from /home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/spdlog.h:12,
from ./src/common/log/Cspdlog.h:6,
from ./src/include/comm_function.h:15,
from ./src/common/table/TableBase.h:5,
from ./src/common/table/TableUser.h:3,
from ./src/common/sql/RiCiDB.h:3,
from ./src/common/wifi/wifiscan.cpp:3:
/home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/fmt/bundled/core.h: In instantiation of 'fmt::v8::detail::value<Context> fmt::v8::detail::make_arg(const T&) [with bool IS_PACKED = true; Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; fmt::v8::detail::type <anonymous> = (fmt::v8::detail::type)15; T = iw_quality; typename std::enable_if<IS_PACKED, int>::type <anonymous> = 0]':
/home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/fmt/bundled/core.h:1694:69: required from 'fmt::v8::format_arg_store<Context, Args>::format_arg_store(const Args& ...) [with Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; Args = {int, int, iw_quality, int, int}]'
/home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/fmt/bundled/core.h:1710:18: required from 'constexpr fmt::v8::format_arg_store<Context, Args ...> fmt::v8::make_format_args(const Args& ...) [with Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; Args = {int, int, iw_quality, int, int}]'
/home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/logger.h:285:97: required from 'void spdlog::logger::log_(spdlog::source_loc, spdlog::level::level_enum, const FormatString&, Args&& ...) [with FormatString = char [43]; Args = {int&, int&, iw_quality&, int&, int&}; Char = char; typename std::enable_if<(! std::is_same<Char, wchar_t>::value), Char>::type* <anonymous> = 0u]'
/home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/logger.h:83:9: required from 'void spdlog::logger::log(spdlog::source_loc, spdlog::level::level_enum, const FormatString&, Args&& ...) [with FormatString = char [43]; Args = {int&, int&, iw_quality&, int&, int&}]'
./src/common/wifi/wifiscan.cpp:737:7: required from here
/home/wingto/work/openwrt-sdk-g001/package/utils/ricigw/src/../../../..//staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/spdlog/fmt/bundled/core.h:1567:3: error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt
static_assert(
^
The error means that an unformattable object is passed to a formatting function. The error message shows that the arguments are:
Args = {int&, int&, iw_quality&, int&, int&}
Since int is formattable it means that iw_quality is the problematic type. To fix this add a formatter specialization for iw_quality:
template <>
struct fmt::formatter<iw_quality> { ... };
See https://fmt.dev/latest/api.html#formatting-user-defined-types for more details on how to implement a formatter.
I try yo compile in C++11 the following piece of code without success. My goal is to use lambda expression instead of bind in order to fill a queue with tasks.
Could you please help me?
Is any case to create a dangling reference ?
#include <iostream>
#include <functional>
#include <queue>
using namespace std;
std::queue<std::function<void()>> funcs;
class A
{
public:
void foo(int a )
{
cout << "Hello word" << endl;
}
};
class ThePool
{
public:
template<typename _Callable, typename Object, typename... _Args>
void QueueFunction(_Callable __f, Object obj, _Args... __args)
{
funcs.push([=]()
{
(obj.*__f)((__args...));
});
}
void print(int i )
{
cout << "Hello Word"<< i <<endl;
}
};
int main(int argc, char** argv) {
ThePool t;
A a ;
t.QueueFunction(&A::foo,a,5);
std::function<void()> func = funcs.back();
func();
return 0;
}
The error that is generated is the following
main.cpp:24:38: error:
parameter packs not expanded with '...':
(obj.__f)((__args...));
^ main.cpp:24:38: note: '__args' main.cpp:24:44: error: expected ')' before '...' token
(obj.__f)((__args...));
^ main.cpp:24:49: error: expected ')' before ';' token
(obj.*__f)((__args...));
^ main.cpp: In function 'int main(int, char**)': main.cpp:39:45: error: conversion
from 'std::function' to non-scalar type
'std::function' requested
std::function func = funcs.back();
^ main.cpp: In instantiation of 'struct ThePool::QueueFunction(_Callable, Object,
_Args ...) [with _Callable = void (A::)(int); Object = A; _Args = {int}]::__lambda0': main.cpp:22:12: required from 'void
ThePool::QueueFunction(_Callable, Object, _Args ...) [with _Callable =
void (A::)(int); Object = A; _Args = {int}]' main.cpp:38:32:
required from here main.cpp:24:38: error: using invalid field
'ThePool::QueueFunction(_Callable, Object, _Args
...)::__lambda0::____args'
(obj.*__f)((__args...));
Why doesn't making threads like this work inside of an abstract base class? I'm trying to abstract away all of the multithreading details for users who derive from this base class. I don't understand why it says "no type named 'type'" when I clearly write that callbackSquare returns type int.
#include <iostream>
#include <future>
#include <vector>
class ABC{
public:
std::vector<std::future<int> > m_results;
ABC(){};
~ABC(){};
virtual int callbackSquare(int& a) = 0;
void doStuffWithCallBack();
};
void ABC::doStuffWithCallBack(){
for(int i = 0; i < 10; ++i)
m_results.push_back(std::async(&ABC::callbackSquare, this, i));
for(int j = 0; j < 10; ++j)
std::cout << m_results[j].get() << "\n";
}
class Derived : public ABC {
Derived() : ABC() {};
~Derived(){};
int callbackSquare(int& a) {return a * a;};
};
int main(int argc, char **argv)
{
std::cout << "testing\n";
return 0;
}
The strange errors I'm getting are:
/usr/include/c++/5/future:1709:67: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/usr/include/c++/5/future:1725:19: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/home/taylor/Documents/ssmworkspace/callbacktest/main.cpp:16:69: required from here
/usr/include/c++/5/functional:1505:61: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/5/functional:1526:9: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
_M_invoke(_Index_tuple<_Indices...>)
Your problem can be reproduced with any function that accepts a reference:
#include <future>
int f(int& a)
{
return a * a;
}
int main()
{
int i = 42;
auto r = std::async(f, i);
}
Accepting a reference in your code is risky since the variable will be modified by the loop iteration, creating a data race because the called function also accesses the variable.
Change the function to accept the input parameter by value, or call std::async by passing std::ref(i) or std::cref(i) (in case the function accepts a const reference) if you acknowledge the risk.
Consider my test code:
#include <thread>
class Foo {
public:
void threadFunc() {}
void startThread() {
_th = std::thread(&Foo::threadFunc, *this);
}
private:
std::thread _th;
};
int main(int argc, char *argv[])
{
Foo f;
f.startThread();
return 0;
}
This is an error it produces:
../untitled/main.cpp:13:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc, char *argv[])
^
../untitled/main.cpp:13:26: warning: unused parameter 'argv' [-Wunused-parameter]
int main(int argc, char *argv[])
^
In file included from ../untitled/main.cpp:1:
In file included from /usr/bin/../lib/c++/v1/thread:90:
In file included from /usr/bin/../lib/c++/v1/__functional_base:15:
/usr/bin/../lib/c++/v1/type_traits:1372:12: error: call to implicitly-deleted copy constructor of 'typename decay<Foo &>::type' (aka 'Foo')
return _VSTD::forward<_Tp>(__t);
^~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/__config:273:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
^
/usr/bin/../lib/c++/v1/thread:351:33: note: in instantiation of function template specialization 'std::__1::__decay_copy<Foo &>' requested here
__decay_copy(_VSTD::forward<_Args>(__args))...));
^
../untitled/main.cpp:7:15: note: in instantiation of function template specialization 'std::__1::thread::thread<void (Foo::*)(), Foo &, void>' requested here
_th = std::thread(&Foo::threadFunc, *this);
^
../untitled/main.cpp:10:17: note: copy constructor of 'Foo' is implicitly deleted because field '_th' has an inaccessible copy constructor
std::thread _th;
^
And if I create a thread like this: _th = std::thread(&Foo::threadFunc, std::ref(*this));
I get:
../untitled/main.cpp:13:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc, char *argv[])
^
../untitled/main.cpp:13:26: warning: unused parameter 'argv' [-Wunused-parameter]
int main(int argc, char *argv[])
^
In file included from ../untitled/main.cpp:1:
/usr/bin/../lib/c++/v1/thread:330:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/usr/bin/../lib/c++/v1/thread:340:5: note: in instantiation of function template specialization 'std::__1::__threaad_execute<void (Foo::*)(), std::__1::reference_wrapper<Foo> , 1>' requested here
__threaad_execute(*__p, _Index());
^
/usr/bin/../lib/c++/v1/thread:352:41: note: in instantiation of function template specialization 'std::__1::__thread_proxy<std::__1::tuple<void (Foo::*)(), std::__1::reference_wrapper<Foo> > >' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
^
../untitled/main.cpp:7:15: note: in instantiation of function template specialization 'std::__1::thread::thread<void (Foo::*)(), std::__1::reference_wrapper<Foo> , void>' requested here
_th = std::thread(&Foo::threadFunc, std::ref(*this));
^
/usr/bin/../lib/c++/v1/type_traits:833:5: note: function has been explicitly marked deleted here
~__nat() = delete;
^
What am I doing wrong? I don't have such problem on Windows with VS2012. I also didn't have this problem with default stdlib implementation on Mac, but now I have to use libc++.
My compiler flags:
-std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++
_th = std::thread(&Foo::threadFunc, *this);
This tries to make a copy of *this to store in the new thread object, but your type is not copyable because its member _th is not copyable.
You probably want to store a pointer to the object, not a copy of the object:
_th = std::thread(&Foo::threadFunc, this);
N.B. your program will terminate because you do not join the thread. In your type's destructor you should do something like:
~Foo() { if (_th.joinable()) _th.join(); }
Hello I'm fallowing a tutorial for pthreading, but something went wrong down the road since can't make the reference to my struct passable by
pthread_create(...,(void* stuctName)) , I'm looking for some advices or fixes since I have no idea where or what I messed up...
code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
struct dataBlock{
struct node *root;
int listSize;
int forIndex;
};
struct node { // std linked list node
int value;
int worker;
struct node *next;
};
int slots = 3; // only 3 threads are allowed to access the list
int availableCheck(){ // check if thread can acces the list
if(slots < 3) return 0;
else return -1;
}
pthread_mutex_t mutp = PTHREAD_MUTEX_INITIALIZER; //condvar mutex
pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; //condvar
void * worker( void *data ){ //WORKER FUNCTION
printf( "* Thread start: ^\n");
struct dataBlock *inData = (struct dataBlock *) data;
struct node *root = data->root;
int listSize = data->listSize;
int forIndex = data ->forIndex;
// printf( " * I am %li _ worker # %li : \n", forIndex, pthread_self() );
pthread_mutex_lock( &mutp );
if(availableCheck() < 0){
printf( " ^^^ List not available yet... \n" );
pthread_cond_wait( &condvar, &mutp );
}
// printf( "* Got data: %lu \n", index );
pthread_cond_signal( &condvar ); //
pthread_mutex_unlock( &mutp );
return NULL;
}
int main( int argc, char *argv[] ){
if ( argc != 3 ){
printf( "Programm must be called with \n NR of elements and NR of workers! \n " );
exit( 1 );
int i;
struct node *root;
struct node *iterator;
//prepare list for task
int listSize = atoi(argv[1]);
int nrWorkers = atoi(argv[2]);
root = malloc(sizeof( struct node) );
root->value = rand() % 100;
root->worker = 0;
iterator = root;
for( i=1; i<listSize; i++ ){
iterator->next = malloc(sizeof(struct node));
iterator = iterator->next;
iterator->value = rand() % 100;
iterator->worker = i % nrWorkers;
printf("node #%d worker: %d value: %d\n", i, iterator->worker,iterator->value);
}
// Create all threads to parse the link list
int ret, *id;
printf("workersInput: %d\n",nrWorkers);
pthread_t w_thread;
pthread_t* w_threads = malloc(nrWorkers * sizeof(w_thread));
struct dataBlock *data = malloc(sizeof(struct dataBlock));
data->root = root;
data->listSize = listSize;
for( i=0; i < nrWorkers; i++ ){ // CREATING THREADS
data->forIndex = i;
ret = pthread_create ( &w_threads[i], NULL, worker, (void *) data );
if( ret ) {
perror("Thread creation fail");
exit(2);
}
}
for ( i = 0; i < nrWorkers; i++){
pthread_join(w_threads[i],NULL);
}
free(root);
free(iterator);
return 0;
}
Compiling(Wall flag)
s.c: In function ‘worker’:
s.c:32:26: warning: dereferencing ‘void *’ pointer [enabled by default]
s.c:32:26: error: request for member ‘root’ in something not a structure or union
s.c:33:22: warning: dereferencing ‘void *’ pointer [enabled by default]
s.c:33:22: error: request for member ‘listSize’ in something not a structure or union
s.c:34:22: warning: dereferencing ‘void *’ pointer [enabled by default]
s.c:34:22: error: request for member ‘forIndex’ in something not a structure or union
s.c:34:6: warning: unused variable ‘forIndex’ [-Wunused-variable]
s.c:33:6: warning: unused variable ‘listSize’ [-Wunused-variable]
s.c:32:15: warning: unused variable ‘root’ [-Wunused-variable]
s.c:31:20: warning: unused variable ‘inData’ [-Wunused-variable]
s.c: In function ‘main’:
s.c:81:12: warning: variable ‘id’ set but not used [-Wunused-but-set-variable]
Use inData->root instead of data->root etc... (or cast explicitly always your data) since data is a void* pointer, that is a pointer to some unspecified data type.